( Table = function()
{

    var myThis;

    //this.tl:TimeLogger = new TimeLogger();
    this.game = null;
    this.jewels = new Array();
    this.tableWidth = 0;
    this.tableHeight = 0;
    this.jewelSize = 55;
    this.qtdJewel = 5;
    this.explosionForce = .1;
    this.tweenTime = .2;
    this.tweening = false;
    this.mcRipples = null;
    this.bdRipple = null;
    this.bdParticulas = null;
    this.bdTemp = null;
    this.bd = null;
    this.bmp = null;
    //this.myParent;//:Game;
    this.arrParticulas;
    this.arrScore = new Array();
    this.displayScore = 0;
    this._displayScore = 0;
    this.displayTime = 0;
    this.speedMult = 0;
    this.comboMult = 0;
    this.superMult = 0;
    this.scoreIced = 0;
    this.scorePure = 0;
    this.scoreAdd = 0;
    this.scoreInfected = 0;
    this.scoreArrow = 0;
    this.scorePowerUps = 0;
    this.scoreDebuff = 0;
    this.scoreDebuffTime = 0;
    this.scoreDebuffMax = 20;
    this.scoreDebuffChances = 3;
    this.scoreDebuffInterval = 1000;
    this.hint = null;//:*;
    this.hintIdle = 3000;
    this.hintTime = 3000;
    this.hintShowAt = 0;
    this.lastAction = 0;
    this.lastUpdate = Tools.getNow();

    this.powerMeters = new Array();
    this.powerLimit = 10;

    this.powerWaves = new Array();
    this.gameFPS = 50;
    this.gameFrames = 0;
    this.iniTime = 0;
    this.gameTime = 0;
    this.totalTime = 60000;
    this.finalTime = this.totalTime;
    this.ending3 = false;
    this.ending10 = false;

    this.bdParticleStar = null;
    this.isFrozen = false;

    this.STATE_NONE = 0;
    this.STATE_BOARD_SETUP = 1;
    this.STATE_PRE_GAME_BONUS = 2;
    this.STATE_PRE_GAME_BONUS_POP = 3;
    this.STATE_PRE_GAME_PRE_COUNTDOWN = 4;
    this.STATE_PRE_GAME_COUNTDOWN = 5;
    this.STATE_GAME = 6;
    this.STATE_PAUSED = 7;
    this.STATE_GAMEOVER = 9;
    this.STATE_REPLAY = 10;

    this.state = this.STATE_BOARD_SETUP;
    this.lastState = this.state;
    this.preGameBonus = 5;
    this.preGameBonusControl = 0;
    this.preGameBonusInterval = 8;
    this.waitTime = 0;
    this.speedBonusMaxInterval = 5000;
    this.speedBonusMinInterval = 1200;
    this.speedBonusInterval = 1200;
    this.lastCombinationTime = -1;
    this.lastFrameTime;
    this.timeBonus = 2000;
    this.freezeTime = 0;
    this.icelvl = 1;
    this.combinations = null;
    this.isolatedJewels = null;
    this.powerJewels = null;
    this.minJewelsInCombination = 3;
    this.doCheck = true;
    this.isGameOver = false;

    this.dropBuffer = new Array();
    this.bgm = null;
    this.particlesBubble = null;//:BubbleParticles;
    this.particlesStar = null;//:StarParticles;
    this.starsPerJewel = 5;

    this.powerUps = new Array();
    this.jt = null;
    this.jtpBi = null;
    this.jtpCross = null;
    this.jtpEspiral = null;
    this.jtpL = null;
    this.jtpMagnet = null;
    this.jtpUni = null;
    this.arrFeedbackVal = [18, 10, 7, 5];
    //this.arrFeedbackVal = [6,5,4,3];
    //this.arrFeedbackVal = [10,8,6,4];
    this.arrFeedback = ["CandyPot!", "excelente", "legal", "bom"];

    //Config
    this.showRollover = false;
    this.autoActivate = false;
    this.bgAlpha = 0;
    this.bgTargetAlpha = 0;
    this.inventory = null;
    this.context2D = null;

    this.jewelsContainer = null;
    this.particlesContainer = null;

    this.arrColors = [0xFFE11A15, 0xFF519FE1, 0xFF219903, 0xFFFAD850, 0xFFBF1099];
    
    this.scales = null;

    this.init = function( w, h, game, jContainer, pContainer )
    {
    	
        myThis = this;
        
        this.scales = Images.calculateScale();
        this.game = game;
        this.jewels = new Array();
        this.w = w | 0;
        this.h = h || 0;
        this.jewelsContainer = jContainer;
        this.particlesContainer = pContainer;

        this.tableWidth = w;
        this.tableHeight = h;
        for ( var i = 0; i < this.tableWidth; i++ )
        {
            this.jewels.push( new Array() );
        }

        this.initPowerMeters();
        this.arrParticulas = new Array();
        this.particlesBubble = new BubbleParticles();
        this.particlesBubble.init( this.particlesContainer );
        this.particlesStar = new StarParticles();
        this.particlesStar.init( this.particlesContainer );

        this.lastUpdate = Tools.getNow();;
        //setInterval( this.destroyRandomCombination, 333 );

        this.reset();

    }

    this.destroyRandomCombination = function()
    {
        if( myThis.state == myThis.STATE_GAME )
        {
            var j
            if( myThis.combinations && myThis.combinations.length > 0 )
            {
                var c = myThis.combinations[Math.floor( Math.random() * myThis.combinations.length )];
                j = c.jewels[0];
                
            }
            else if ( myThis.powerJewels && myThis.powerJewels.length > 0 )
            {
                j = myThis.powerJewels[Math.floor( Math.random() * myThis.powerJewels.length )]
            }

            if ( j )
            {
                var pt = myThis.jewelsContainer.localToGlobal( 0, 0 );
                myThis.clickJewel( pt.x + j.x * myThis.jewelSize + 5, pt.y + j.y * myThis.jewelSize + 5 );
            }
            
        }
    }

    this.playBgMusic = function()
    {
        GameSounds.playBgMusic();
    }

    this.playHit = function()
    {
        var hitCount = ( this.speedMult > 10 ) ? 10 : ( this.speedMult < 0 ) ? 1 : ( this.speedMult == 0 ) ? 10 : this.speedMult;

        if ( this.comboMult > 10 )
        {
            GameSounds.playHitCombo( hitCount );
        }
        else
        {
            GameSounds.playCombination( this.comboMult );
        }
    }

    this.reset = function()
    {
        for ( var i = 0; i < this.qtdJewel + 1; i++ )
        {
            this.arrScore[i] = 0;
        }

        this.initPowerMeters();

        this.displayScore = this._displayScore = 0;

        this.scoreIced = this.scorePure = this.scoreAdd = this.scoreInfected = this.scoreArrow = this.scorePowerUps = 0;

        this.speedBonusInterval = this.speedBonusMaxInterval;

        this.scoreDebuff = 0;
        this.speedMult = 0;
        this.comboMult = 0;
        this.superMult = 0;
        this.preGameBonusControl = 0;
        this.lastFrameTime = Tools.getNow();
        this.lastCombinationTime = Tools.getNow();
        this.finalTime = this.totalTime;
        this.iniTime = Tools.getNow();
        this.gameTime = 0;
        this.gameFrames = 0;
        this.ending3 = false;
        this.ending10 = false;

        this.initPowerUps();
        this.startGame();
        this.isGameOver = false;
        this.refill();

    }

    this.loadError = function( e )
    {
        trace( "ERROR" );
        trace( e.text );
    }

    this.startGame = function()
    {
        if ( this.state == this.STATE_PAUSED )
        {
            this.lastState = STATE_BOARD_SETUP;
        }
        else
        {
            this.state = this.STATE_BOARD_SETUP;
        }
        this.waitTime = 20;

        this.game.onStartGame();
    }

    this.gameOver = function()
    {
        this.isGameOver = true;
        this.updateScore();
        this.game.onEndGame( new ScoreData( this.displayScore ) );
    }

    this.customFill = function()
    {
        /**/
        //Test super creation	
        var myTable = "12243434" +
                      "21134343" +
                      "34343434" +
                      "43434343" +
                      "34343434" +
                      "43434343" +
                      "34343434" +
                      "43434343";
        //*/

        /*
        //Test super explosion	
        var myTable = "34343434" +
                      "43439343" +
                      "34385434" +
                      "43434343" +
                      "38343434" +
                      "45934343" +
                      "34343434" +
                      "43434343";
        //*/

        /*
        //Test combination	
        var myTable = "34343434" +
                      "43434343" +
                      "34345434" +
                      "43556343" +
                      "34343434" +
                      "43434343" +
                      "34343434" +
                      "43434343";
         //*/


        for ( var i = 0; i < myTable.length; i++ )
        {
            var ix = i % 8;
            var iy = Math.floor( i / 8 );
            var jType = parseInt( myTable.substr( i, 1 ) );

            //trace( "CF: " + ix + "," + iy + " - " + jType );

            var j = new Jewel( jType );
            this.addJewel( j );
            this.jewels[ix][iy] = j;
            j.x = ix * this.jewelSize;
            j.y = iy * this.jewelSize;
        }

        this.calcGround();
    }

    this.onRemove = function( event/*:Event*/ )
    {
        //this.removeEventListener( Event.ENTERFRAME, ef );
        //this.removeEventListener( Event.REMOVEDFROMSTAGE, onRemove );
        //this.removeEventListener( MouseEvent.MOUSEDOWN, clickJewel );

        this.jt = null;
        this.jtpBi = null;
        this.jtpCross = null;
        this.jtpEspiral = null;
        this.jtpL = null;
        this.jtpMagnet = null;
        this.jtpUni = null;
    }

    this.ef = function()
    {
        var now = Tools.getNow();
        var delta = now - this.lastUpdate;
        //if( delta < 0 ) delta = 0;
        var fr = ( delta / ( 1000 / this.gameFPS ) );
        var f;
        this.lastUpdate = now - ( delta % ( 1000 / this.gameFPS ) );

        if ( this.state != this.STATE_PAUSED && this.state != this.STATE_NONE ) this.gameFrames += fr;

        //UPDATE FROM HUD
        /*
        qtdJewel = parseInt( myParent["mcHud"].txtGems.text );
        powerLimit = parseInt( myParent["mcHud"].txtLimit.text );
        speedBonusInterval = parseInt( myParent["mcHud"].txtInterval.text );
        */

        var allSleeping = true;
        var showHint = this.state == this.STATE_GAME && !this.isGameOver && ( ( now - this.lastAction ) > this.hintIdle );
        var clipRect = new createjs.Rectangle( 0, 0, 40, 40 );
        var pDraw = new createjs.Point();

        var mDraw = new createjs.Matrix2D();
        var val = 1 + ( ( this.speedMult >= 10 || this.showHint ) ? ( ( Math.cos(( Math.PI / 180 ) * ( now / 4 % 360 ) ) ) * .3 ) : 0 );


        this.bgTargetAlpha = Number(( this.comboMult > 5 ) ? ( this.comboMult - 5 ) / 6 : 0 );
        this.bgAlpha += ( this.bgTargetAlpha - this.bgAlpha ) / 30;

        var jewel;
        var moves = 0;

        for ( var i = 0; i < this.powerWaves.length; i++ )
        {
            w = this.powerWaves[i];
            for ( f = 0; f < fr; f++ )
            {
                if ( w.active )
                {
                    w.update();
                }
                else
                {
                    //Remove old wave;
                    w.destroy();
                    this.powerWaves.splice( this.powerWaves.indexOf( w ), 1 );
                    break;
                }
            }
            this.findAllCombinations();
        }

        for ( var i = 0; i < this.tableWidth; i++ )
        {
            for ( var j = 0; j < this.tableHeight; j++ )
            {
                jewel = this.getJewelAt( i, j );
                if ( jewel == null ) continue;

                for ( f = 0; f < fr; f++ )
                {
                    jewel.update();
                }

                allSleeping = allSleeping && jewel.isSleeping;

                mDraw.tx = pDraw.x = clipRect.x = jewel.x;
                mDraw.ty = pDraw.y = clipRect.y = jewel.y;

                mDraw.tx -= jewel.spriteRect.x;
                mDraw.ty -= jewel.spriteRect.y;

                if ( this.state == this.STATE_PAUSED )
                {
                    jewel.setSheet( Images.getImage( Images.FROZEN_JEWELS ) );
                    jewel.spriteRect.x = jewel.spriteRect.y = 0;
                }
                else
                {
                    var bmp;
                    bmp = this.jt;

                    if ( jewel.hasSuperPower() )
                    {
                        switch ( jewel.powerUpId )
                        {
                            case PowerUP.POWERUPBIDIRECIONAL:
                                bmp = this.jtpBi;
                                break;

                            case PowerUP.POWERUPCROSS:
                                bmp = this.jtpCross;
                                break;

                            case PowerUP.POWERUPESPIRAL:
                                bmp = this.jtpEspiral;
                                break;

                            case PowerUP.POWERUPLWAVE:
                                bmp = this.jtpL;
                                break;

                            case PowerUP.POWERUPMAGNET:
                                bmp = this.jtpMagnet;
                                break;

                            case PowerUP.POWERUPUNIDIRECIONAL:
                                bmp = this.jtpUni;
                                break;

                        }
                    }

                    jewel.setSheet( bmp );


                    if ( this.speedMult >= 10 )
                    {
                        //TODO: this.bd.draw( this.bmp, this.mDraw, this.ct, null, clipRect );
                    }
                    else if ( this.showHint && hint != null )
                    {
                        //TODO: Check this
                        //if( (hint is Combination && Combination( hint ).containsPoint( new createjs.Point(i, j) )) || (hint is Point && Point( hint ).x == i && Point( hint ).y == j ) )
                        //{
                        //    bd.draw( bmp, mDraw, ct, null, clipRect );
                        //}
                        //else
                        //{
                        //    bd.copyPixels( bmp, jewel.spriteRect, pDraw, null, null, true); 
                        //}
                    }
                    else
                    {
                        //this.myDraw( bmp, jewel.spriteRect, pDraw );
                    }

                    if ( jewel.shineFrame > 0 )
                    {
                        //this.myDraw( this.jt, new createjs.Point(( jewel.shineFrame - 2 ) * this.jewelSize, 7 * this.jewelSize ), pDraw );
                    }
                    else if ( jewel.hasSuperPower() && Math.random() > .99 )
                    {
                        jewel.shineFrame = 1;
                    }

                }
            }
        }

        var len = this.particlesBubble.getLength();
        if ( len > 0 )
        {
            for ( f = 0; f < fr; f++ )
            {
                this.particlesBubble.update();
            }
        }

        len = this.particlesStar.getLength()
        if ( len > 0 )
        {
            for ( f = 0; f < fr; f++ )
            {
                this.particlesStar.update();
            }
        }



        if ( this.showRollover )
        {
            this.drawCombination( isInAnyCombination( Math.floor( this.mouseX / this.jewelSize ), Math.floor( this.mouseY / this.jewelSize ) ) );
        }
        var p = 0;
        for ( f = 0; f < fr; f++ )
        {

            if ( this.waitTime > 0 ) this.waitTime--;
            if ( this.waitTime > 0 )
            {
                switch ( this.state )
                {
                    case this.STATE_PRE_GAME_COUNTDOWN:
                        {
                            //var mc = new createjs.MovieClip();
                            //mc.createjs.( mc.currentFrame );

                            //myParent["countdown"].nextFrame();
                            break;
                        }
                }
            }
            else
            {
                switch ( this.state )
                {
                    case this.STATE_BOARD_SETUP:
                        this.state = this.STATE_PRE_GAME_BONUS;
                        this.waitTime = this.preGameBonusInterval;
                        break;

                    case this.STATE_PRE_GAME_BONUS:
                        this.preGameBonusControl++;
                        this.waitTime = this.preGameBonusInterval;
                        this.state = this.STATE_PRE_GAME_BONUS_POP;
                        this.waitTime = 60;
                        break;

                    case this.STATE_PRE_GAME_BONUS_POP:
                        if ( this.powerJewels.length > 0 )
                        {
                            this.activateJewelSuperPower( this.powerJewels[0] );
                            this.waitTime = 5;
                        }
                        else
                        {
                            this.state = this.STATE_PRE_GAME_PRE_COUNTDOWN;
                            this.waitTime = 30;
                        }
                        break;

                    case this.STATE_PRE_GAME_PRE_COUNTDOWN:

                        GameSounds.playReady();
                        var tween = new createjs.Tween();
                        tween.wait( 69 ).call( GameSounds.playGo );
                        //TweenLite.delayedCall( 69, //GameSounds.playGo, null, true );
                        this.state = this.STATE_PRE_GAME_COUNTDOWN;
                        //myParent.addChild( myParent["countdown"] );
                        //myParent["countdown"].createjs.( 1 );
                        //waitTime = myParent["countdown"].totalFrames;
                        break;

                    case this.STATE_PRE_GAME_COUNTDOWN:
                        this.state = this.STATE_GAME;
                        this.lastFrameTime = this.lastAction = now;
                        //this.myParent.removeChild( myParent["countdown"] );
                        break;

                    case this.STATE_GAME:

                        if ( this.isFrozen )
                        {
                            this.freezeTime -= ( now - this.lastFrameTime );
                            this.lastFrameTime = now;
                            if ( this.freezeTime <= 0 )
                            {
                                this.gameTime += -this.freezeTime;
                                this.isFrozen = false;
                            }
                        }
                        else
                        {

                            this.gameTime += now - this.lastFrameTime;
                            this.lastFrameTime = now;

                            if ( !this.ending3 && ( this.totalTime - this.gameTime < 3000 ) )
                            {
                                GameSounds.playTimeOver3();
                                this.ending3 = true;
                            }
                            if ( !this.ending10 && ( this.totalTime - this.gameTime < 10000 ) )
                            {
                                GameSounds.playTimeOver10();
                                this.ending10 = true;
                            }

                        }

                        if ( this.gameTime >= this.totalTime )
                        {
                            this.speedMult = 0;
                            if ( !this.isGameOver )
                            {

                                this.gameTime = this.totalTime;
                                this.state = this.STATE_GAMEOVER;
                                GameSounds.playGameOver();
                                //myParent.scene.gi.hideBottomButtons();
                                //myParent.addChild( myParent.jogoFim );
                                //myParent.jogoFim.play();
                                this.waitTime = 150;
                            }
                        }

                        break;

                    case this.STATE_GAMEOVER:
                        if ( !this.isGameOver ) this.gameOver();
                        break;

                    case this.STATE_PAUSED:
                        {
                            this.lastFrameTime = now;
                            break;
                        }
                }

            }

        }

        if ( now - this.lastCombinationTime > this.speedBonusInterval )
        {
            this.decreaseSpeedMult();
        }

        if ( now - this.scoreDebuffTime > this.scoreDebuffInterval )
        {
            this.decreaseDebuff();
        }

        if ( this.game.bearAnimation )
        {
            this.game.bearAnimation.update( this.comboMult );
        }
        if ( this.game.borderAnimation )
        {
            if ( this.comboMult >= 10 )
            {
                this.game.borderAnimation.gotoAndStop( "super_combo" );
                this.game.startSnowCombo();
            }
            else if ( this.comboMult >= 1 )
            {
                this.game.borderAnimation.gotoAndStop( "combo" );
                this.game.stopSnowCombo();
            }
            else
            {
                this.game.borderAnimation.gotoAndStop( "normal" );
                this.game.stopSnowCombo();
            }
        }
        this.updateHud();
    }

    this.myDraw = function( bmp, src, dest )
    {
        //Images.context.drawImage( bmp, src.x, src.y, this.jewelSize, this.jewelSize, dest.x, dest.y, this.jewelSize, this.jewelSize );
    }

    this.refill = function()
    {
        this.clear();
        this.fill();

        for ( var i = 0; i < this.preGameBonus; i++ )
        {
            this.createSuddenPowerUp( false, false, true );
        }


    }

    this.clear = function( explode )// = false )
    {
        explode = explode || false;
        for ( var i = 0; i < this.tableWidth; i++ )
        {
            for ( var j = 0; j < this.tableHeight; j++ )
            {
                var jewel = this.jewels[i][j];
                if ( jewel != null )
                {
                    if ( explode ) this.explodeJewel( i, j ); //HUGE performance issues...
                    this.jewels[i][j] = null;
                }
            }
        }

    }

    this.createNewRandomJewel = function( p )
    {
        var j = new Jewel();
        this.addJewel( j );
        j.init( this.getRandomType() );
        if ( this.dropBuffer.length > 0 && Math.random() < .8 )
        {
            var buffer = this.dropBuffer.shift();
            j.type = buffer.type;
            j.setPowerUp( buffer.powerUp, p );
            j.isTimer = buffer.isTimer;
        }

        return j;
    }

    this.getRandomType = function()
    {
        return Math.floor( Math.random() * ( this.qtdJewel ) ) + 1;
    }

    this.fill = function()
    {
        //if( isGameOver ) return;

        //if( isReplay ) return;

        var changed = true;

        while ( changed )
        {
            changed = false;
            for ( var x = 0; x < this.tableWidth; x++ )
            {
                if ( this.getJewelAt( x, 0 ) == null )
                {
                    changed = true;
                    var j = this.createNewRandomJewel( new createjs.Point( x, 0 ) );

                    var minY = Number.MAX_VALUE;
                    for ( var i = this.tableHeight - 1; i >= 0; i-- )
                    {
                        if ( this.jewels[x][i] != null )
                        {
                            minY = Math.min( minY, this.jewels[x][i].y );
                            j.speed.y = this.jewels[x][i].speed.y - this.explosionForce;
                        }
                    }

                    if ( minY > 0 )
                    {
                        minY = 0;
                    }

                    j.x = x * this.jewelSize;
                    j.y = minY - this.jewelSize;

                    //gl.addLog( GameLog.ACTIONNEWJEWEL, {j:j.info, px:x, py:0 } );

                    this.jewels[x][0] = j;
                    this.drop();

                }
            }
        }

        this.findAllCombinations();

    }

    this.clickJewel = function( mx, my )//:MouseEvent) 
    {

        this.lastAction = Tools.getNow();

        if ( this.tweening || this.isGameOver || this.state != this.STATE_GAME ) return;
        var pt = this.jewelsContainer.localToGlobal( 0, 0 );
        var scaleX = this.jewelsContainer.scaleX;
        var scaleY = this.jewelsContainer.scaleY;
        var jx = Math.floor(( mx - pt.x ) / ( this.jewelSize * scaleX ) );
        var jy = Math.floor(( my - pt.y ) / ( this.jewelSize * scaleY ) );
        var jewel = this.getJewelAt( jx, jy );

        var mc = new createjs.MovieClip();
        mc.localToGlobal( 0, 0 );

        if ( jewel == null || !jewel.isSleeping ) return;
        
        //if( Tools.gravity.y < .7 )
        //{
        //    this.setJewel( new createjs.Point(jx, jy), jewel.type, this.getRandomPowerUpForType( jewel.type ) );
        //    return;
        //}

        /*
        else if( event.altKey )
        {
            createTimerJewel();
            //jewel.isTimer = true;
            //createSuddenPowerUp();
            return;
        }
        else if( event.shiftKey )
        {
        
            for (var ix = 0; ix < this.tableWidth; ix++) 
            {
                for (var iy = 0; iy < this.tableHeight; iy++) 
                {
                    var jj:Jewel = this.getJewelAt(ix, iy);
                    if( jj == null ) continue;
                    if( jj.infected ) jj.flash();
                }
            }
            
            return;
        }
        */


        if ( jewel.hasSuperPower() )
        {
            if ( jewel.powerUpId == PowerUP.POWERUPUNIDIRECIONAL )
            {
                this.scorePowerUps += ( jewel.powerUp.level == 1 ) ? 2000 : ( jewel.powerUp.level == 2 ) ? 13000 : 25000;
            }
            else if ( jewel.powerUpId == PowerUP.POWERUPLWAVE )
            {
                this.scorePowerUps += ( jewel.powerUp.level == 1 ) ? 6000 : ( jewel.powerUp.level == 2 ) ? 20000 : 30000;
            }
            else if ( jewel.powerUpId == PowerUP.POWERUPESPIRAL )
            {
                this.scorePowerUps += ( jewel.powerUp.level == 1 ) ? 10000 : ( jewel.powerUp.level == 2 ) ? 25000 : 35000;
            }
            else if ( jewel.powerUpId == PowerUP.POWERUPMAGNET )
            {
                this.scorePowerUps += ( jewel.powerUp.level == 1 ) ? 25000 : ( jewel.powerUp.level == 2 ) ? 35000 : 45000;
            }

            this.updateScore();
            this.activateJewelSuperPower( new createjs.Point( jx, jy ) );
            this.lastCombinationTime = Tools.getNow();
        }
        else
        {
            var c = this.isInAnyCombination( jx, jy ); //findCombinationFrom( jx, jy );

            if ( c != null )
            {

                var activatedPower = false;

                if ( this.autoActivate )
                {
                    for ( var i = 0; i < c.jewels.length; i++ )
                    {
                        var p = c.jewels[i];
                        var iyy = this.getJewelAt( p.x, p.y );
                        if ( iyy.hasSuperPower() )
                        {
                            this.activateJewelSuperPower( p );
                            activatedPower = true;
                        }
                    }
                    this.lastCombinationTime = Tools.getNow();

                }

                if ( !activatedPower && c.size() >= this.minJewelsInCombination )
                {
                    //Speed bonus
                    if ( this.lastCombinationTime > 0 && Tools.getNow() - this.lastCombinationTime < this.speedBonusInterval )
                    {
                        this.increaseSpeedMult();
                    }

                    if ( c.size() >= this.arrFeedbackVal[0] )
                    {
                        GameSounds.playCandypotHit();
                    }

                    //gl.addLog( GameLog.ACTIONDESTROYCOMBINATION, {px:jx, py:jy, sm:speedMult} );
                    this.destroyCombination( c );
                    this.lastCombinationTime = Tools.getNow();

                }
                else
                {
                    this.increaseDebuff();
                    this.decreaseSpeedMult();
                }

            }
            else
            {
                //Logger.addLog( "MISS" );
                //jewel.ops();
                var combMiss = this.findCombinationFrom( jx, jy );
                //for each( var jm:Point in combMiss.jewels )
                for ( var i = 0; i < combMiss.jewels.length; i++ )
                {
                    var jm = combMiss.jewels[i];
                    this.getJewelAt( jm.x, jm.y ).desaturate();
                }
                this.increaseDebuff();
                this.decreaseSpeedMult();
            }
        }
    }

    this.drop = function()
    {
        for ( var x = 0; x < this.tableWidth; x++ )
        {
            for ( var y = this.tableHeight - 1; y > 0; y-- )
            {
                if ( this.getJewelAt( x, y ) == null )
                {
                    for ( var i = y - 1; i >= 0; i-- )
                    {
                        var j = this.getJewelAt( x, i );
                        if ( j != null )
                        {
                            this.jewels[x][y] = j;
                            this.jewels[x][i] = null;
                            break;
                        }
                    }
                }
            }
        }
        this.calcGround();
        //gl.addLog( GameLog.ACTIONDROP, {} );
    }

    this.getJewelAt = function( x, y )//:Jewel
    {
        if ( x < 0 || x > this.tableWidth - 1 || y < 0 || y > this.tableHeight - 1 ) return null;
        return this.jewels[x][y];
    }

    this.calcGround = function()
    {
        for ( var x = 0; x < this.tableWidth; x++ )
        {
            for ( var y = 0; y < this.tableHeight; y++ )
            {
                var jewel/*:Jewel*/ = this.getJewelAt( x, y );
                if ( jewel != null )
                {
                    jewel.ground = new createjs.Point( x * this.jewelSize, y * this.jewelSize );
                }
            }
        }
    }

    this.findCombinationFrom = function( x, y )//:Combination
    {

        var j/*:Jewel*/ = this.getJewelAt( x, y );

        if ( j != null )
        {
            var c = new Combination();
            c.init( j.type );
            this.addEqualNeightboursToCombination( x, y, c );
            return c;
        }

        return null;

    }

    this.findAllCombinations = function()
    {
        //var combinations = new Array();
        this.combinations = new Array();//= new Vector.<Combination>();
        this.isolatedJewels = new Array(); // = new Vector.<Point>();
        this.powerJewels = new Array(); //= new Vector.<Point>();

        for ( var x = 0; x < this.tableWidth; x++ )
        {
            for ( var y = 0; y < this.tableHeight; y++ )
            {
                var j = this.getJewelAt( x, y );
                if ( j == null ) continue;

                if ( j.hasSuperPower() )
                {
                    this.powerJewels.push( new createjs.Point( x, y ) );
                }
                else if ( !this.isInAnyCombination( x, y ) )
                {

                    var c = this.findCombinationFrom( x, y );

                    if ( c != null && c.size() >= this.minJewelsInCombination )
                    {
                        this.combinations.push( c );
                    }
                    else if ( !j.isTimer )
                    {
                        this.isolatedJewels.push( new createjs.Point( x, y ) );
                    }
                }

            }
        }

        if ( this.combinations.length + this.powerJewels.length <= 3 )
        {
            this.hint = null;
            this.createSuddenPowerUp();
        }
        else
        {
            if ( this.combinations.length > 0 )
            {
                this.hint = this.combinations[Math.round( Math.random() * ( this.combinations.length - 1 ) )];
            }
            else
            {
                this.hint = this.powerJewels[Math.round( Math.random() * ( this.powerJewels.length - 1 ) )];
            }
        }

    }

    this.isInAnyCombination = function( x, y )//:Combination
    {
        var p = new createjs.Point( x, y );
        //for each( var c:Combination in combinations )
        for ( var i = 0; i < this.combinations.length; i++ )
        {
            var c = this.combinations[i];
            if ( c.containsPoint( p ) ) return c
        }
        return null;
    }

    this.addEqualNeightboursToCombination = function( x, y, c )//:Combination )
    {
        var p = new createjs.Point( x, y );

        if ( !c.containsPoint( p ) )
        {
            var j = this.getJewelAt( x, y );

            //if( j != null && !j.hasSuperPower && j.type == c.type )
            if ( ( j != undefined && j != null ) && j.type == c.type )
            {
                c.addPoint( p );
                this.addEqualNeightboursToCombination( x - 1, y, c );
                this.addEqualNeightboursToCombination( x + 1, y, c );
                this.addEqualNeightboursToCombination( x, y - 1, c );
                this.addEqualNeightboursToCombination( x, y + 1, c );

            }

        }

    }

    this.addCombination = function( c )//:Combination )
    {
        //trace( "ADD COMB: " + c.jewels.length );
        /*
        for each( var comb:Combination in combinations )
        {
            if( comb.intersects(c) )
            {
                comb.merge(c);
                return;
            }
        }
        */
        this.combinations.push( c );
    }

    this.isAlreadyInCombination = function( p )//:Point )
    {
        //for each( var comb:Combination in combinations )
        for ( var comb in combinations )
        {
            if ( comb.containsPoint( p ) ) return true;
        }
        return false;
    }

    this.addScore = function( c, noMoves )//:Combination, noMoves = false )
    {

        var debuff = 1 - ( ( this.scoreDebuff <= this.scoreDebuffChances ? 0 : ( ( this.scoreDebuff - this.scoreDebuffChances ) / ( this.scoreDebuffMax - this.scoreDebuffChances ) ) ) * .9 );
        var buff = 1 + ( Math.min( 10, this.comboMult ) / 10 ); //comboMult has a maximum of 10.

        //if( isGameOver ) return;
        var sc = 0;
        var i = 0;
        if ( c == null && noMoves )
        {
            i = 0;
            sc = 300;
        }
        else
        {
            i = c.type;
            //150 points per jewel + 10 for each passing the size of 3...like:
            //150 150 150 160 170 180 190...

            var add = 0;
            if ( c.size() - 3 > 0 )
            {
                for ( var a = 1; a <= ( c.size() - 3 ) ; a++ )
                {
                    add += ( a * 25 ) * debuff * buff;
                }
            }
            this.scoreAdd += add;

            //for each( var p:Point in c.jewels )
            for ( var n = 0; n < c.jewels.length; n++ )
            {
                var p = c.jewels[n];
                if ( this.getJewelAt( p.x, p.y ).infected )
                {
                    add += 150 * debuff * buff;
                    this.scoreInfected += 150 * debuff * buff;
                }
            }

            this.scorePure += ( c.size() * 150 ) * debuff * buff;
            sc = ( ( c.size() * 150 ) * debuff * buff ) + add;
        }

        this.arrScore[i] += sc;

        this.updateScore();

    }

    this.updateScore = function()
    {
        this.displayScore = 0;
        //for each( var s in arrScore )
        for ( var i = 0; i < this.arrScore.length; i++ )
        {
            var s = this.arrScore[i];
            this.displayScore += parseInt( s );
        }
        this.displayScore += this.scoreIced;
        this.displayScore += this.scorePowerUps;
    }

    this.updateHud = function()
    {
        this.displayTime = Math.floor(( this.totalTime - this.gameTime ) / 1000 );
        this._displayScore = Math.min( this._displayScore + parseInt( Math.random() * ( ( this.displayScore - this._displayScore ) / 5 ) ) + 1, this.displayScore );

        this.game.clock.fill( this.gameTime / this.totalTime );
        this.game.clock.setTime( this.displayTime );
        this.game.clock.setScore( Tools.formatVal( this.getScore() ) );
        //this.clock.setFreeze( isFrozen );
    }

    this.getScore = function()
    {
        return this._displayScore;
    }

    this.hasCombination = function( x, y )
    {

        return this.checkNeighbours( x, y, 2, 0, 1, 0 ) ||
               this.checkNeighbours( x, y, 1, 1, 1, 0 ) ||
               this.checkNeighbours( x, y, 1, 1, 0, 1 ) ||
               this.checkNeighbours( x, y, 0, 2, 0, 1 ) ||
               this.checkNeighbours( x, y, -1, 1, 0, 1 ) ||
               this.checkNeighbours( x, y, -1, 1, -1, 0 ) ||
               this.checkNeighbours( x, y, -2, 0, -1, 0 ) ||
               this.checkNeighbours( x, y, -1, -1, -1, 0 ) ||
               this.checkNeighbours( x, y, -1, -1, 0, -1 ) ||
               this.checkNeighbours( x, y, 0, -2, 0, -1 ) ||
               this.checkNeighbours( x, y, 1, -1, 0, -1 ) ||
               this.checkNeighbours( x, y, 1, -1, 1, 0 ) ||
               this.checkNeighbours( x, y, 1, 1, 0, -2 ) ||
               this.checkNeighbours( x, y, -1, 1, 2, 0 ) ||
               this.checkNeighbours( x, y, -1, -1, 0, 2 ) ||
               this.checkNeighbours( x, y, 1, -1, -2, 0 );

    }

    this.checkNeighbours = function( x, y, dX, dY, nextX, nextY )
    {
        if ( x + dX < 0 || x + dX > this.tableWidth - 1 ||
            y + dY < 0 || y + dY > this.tableHeight - 1 ||
            this.getJewelAt( x + dX, y + dY ) == null ||
            this.getJewelAt( x + dX + nextX, y + dY + nextY ) == null ) return false;

        return ( ( this.getJewelAt( x, y ).type == this.getJewelAt( x + dX, y + dY ).type ) &&
                ( this.getJewelAt( x, y ).type == this.getJewelAt( x + dX + nextX, y + dY + nextY ).type ) );

    }

    this.destroyCombination = function( c )
    {

        var index = this.combinations.indexOf( c );
        if ( index > -1 )
        {
            this.combinations.splice( index, 1 );
        }

        for ( var i = 0; i < this.arrFeedbackVal.length; i++ )
        {
            if ( c.size() >= this.arrFeedbackVal[i] )
            {
                if ( i == 1 ) this.game.bearAnimation.animExcelente();
                else if ( i == 2 ) this.game.bearAnimation.animLegal();
                else if ( i == 3 ) this.game.bearAnimation.animBom();
                //this.showFeedback( this.arrFeedback[i] );
                break;
            }
        }

        for ( var i = 0; i < c.jewels.length; i++ )
        {
            var p = c.jewels[i]
            if ( this.getJewelAt( p.x, p.y ).isTimer )
            {
                this.freezeTime += this.timeBonus;
                this.isFrozen = true;
                this.finalTime += this.timeBonus;
                this.showFeedback( "Tempo Extra!" );
                GameSounds.playFreeze();
                this.scoreIced += ( this.icelvl == 1 ) ? 10000 : ( this.icelvl == 2 ) ? 15000 : 20000;
            }
        }


        this.addPower( c );
        this.addScore( c );

        this.createParticlesForCombination( c, 10 + ( ( c.size() - 3 ) * 1 ) );
        this.destroyJewels( c );

        this.playHit();

        this.lastCombinationTime = Tools.getNow();

        this.drop();
        this.fill();


    }

    this.showFeedback = function( txt )
    {
        //myParent["feedbackText"].createjs.( txt );
        //myParent["feedbackText"]["mcAnim"].gotoAndPlay( 1 );
        //myParent["txtFeedback"].text = txt;
        //myParent["txtFeedback"].alpha = 1;
    }

    this.checkSuperNeightbour = function( x, y, checkType )
    {

        //return 0 for none, 1 right, 2 down, 3 left, 4 top.

        if ( this.getJewelAt( x + 1, y ) && this.getJewelAt( x + 1, y ).type == checkType ) return 1;
        if ( this.getJewelAt( x, y + 1 ) && this.getJewelAt( x, y + 1 ).type == checkType ) return 2;
        if ( this.getJewelAt( x - 1, y ) && this.getJewelAt( x - 1, y ).type == checkType ) return 3;
        if ( this.getJewelAt( x, y - 1 ) && this.getJewelAt( x, y - 1 ).type == checkType ) return 4;
        return 0;

    }

    this.getAmountOfEqualNeightbours = function( jewel, x, y, dir, m ) //(jewel:Jewel, x, y, dir:Point, m=0) 
    {
        m = m || 0;

        if ( x + dir.x < 0 || x + dir.x > this.tableWidth - 1 || y + dir.y < 0 || y + dir.y > this.tableHeight - 1 ) return m;

        if ( this.getJewelAt( x + dir.x, y + dir.y ).type == jewel.type )
        {
            return this.getAmountOfEqualNeightbours( jewel, x + dir.x, y + dir.y, dir, m + 1 );
        }

        return m;
    }

    this.destroyJewels = function( combination )
    {

        //trace( rect );

        for ( var i = 0; i < combination.jewels.length; i++ )
        {
            var p = combination.jewels[i]
            if ( this.getJewelAt( p.x, p.y ) == null ) continue;

            this.explodeJewel( p.x, p.y );
            this.jewels[p.x][p.y] = null;
        }

    }

    this.explodeJewel = function( x, y )
    {
        var jewel = this.getJewelAt( x, y );
        this.removeJewel( jewel );
        for ( var i = y; i >= 0; i-- )
        {
            if ( this.jewels[x][i] != null )
            {
                this.jewels[x][i].speed.y = -3 - ( ( this.tableHeight - i ) * this.explosionForce );
            }
        }

    }

    this.draw = function( g )
    {
        var arrColors = new Array( "#FF0000", "#FF9900", "#FFFF00", "#FF00FF", "#0000FF", "#999999", "#0000FF" );
        g.clear();
        for ( var x = 0; x < this.tableWidth; x++ )
        {
            for ( var y = 0; y < this.tableHeight; y++ )
            {
                var jewel = this.getJewelAt( x, y );
                var color = arrColors[jewel.type - 1];
                if ( jewel.hasSuperPower() )
                {
                    g.beginStroke( "#000" );
                }

                g.beginFill( color );
                g.drawRect( jewel.x, jewel.y, this.jewelSize, this.jewelSize );

                if ( jewel.hasSuperPower() )
                {
                    g.endStroke();
                }
                g.endFill();
            }
        }


    }

    this.createRipple = function( posX, posY )
    {
        /*
        var mc = new AniRipple();
        mc.x = posX;
        mc.y = posY;
        mcRipples.addChild( mc );
        */
    }

    this.createParticulas = function( jewel, x, y )
    {
        var p;

        var bdRef = new createjs.BitmapData( this.jewelSize, this.jewelSize, true, 0x00000000 );
        bdRef.copyPixels( jt, jewel.spriteRect, new createjs.Point() );

        var power = 1;

        for ( var ix = 1; ix <= bdRef.width; ix += 2 )
        {
            for ( var iy = 1; iy <= bdRef.height; iy += 2 )
            {
                var color = new Color32( bdRef.getPixel32( ix, iy ) );
                if ( color.getA > 30 && ( Math.random() < .4 ) )
                {
                    var rad = Math.atan2( iy - this.jewelSize / 2, ix - this.jewelSize / 2 );
                    var dist = Math.sqrt( Math.pow( this.jewelSize / 2 - ix, 2 ) + Math.pow( this.jewelSize / 2 - iy, 2 ) );
                    p = new Particula( Math.random() * 30, x + Math.cos( rad ) * dist, y + Math.sin( rad ) * dist, Math.cos( rad ) * ( Math.random() * dist ) / 5 * power, Math.sin( rad ) * ( Math.random() * dist ) / 5 * power, color.getColor ); //Math.cos(rad) * 5, Math.sin(rad) * 5, color.getColor );
                    arrParticulas.push( p );
                }
            }
        }
    }

    this.createParticlesForCombination = function( c, amount )//( c:Combination, amount )
    {

        var amountPerJewel = Math.round( amount / c.size() );


        for ( var i = 0; i < c.jewels.length; i++ )
        {
            var p = c.jewels[i];
            this.createParticlesForJewel( p, amountPerJewel );
        }
    }

    this.createParticlesForJewel = function( p, amount )
    {
        //amount *= 2;
        var jewel = this.getJewelAt( p.x, p.y );

        for ( var i = 0; i < amount; i++ )
        {
            var ix = this.jewelSize / 2 + Math.round( Math.random() * 20 - 10 );
            var iy = this.jewelSize / 2 + Math.round( Math.random() * 20 - 10 );

            var c = 0x0;
            var power = 1;
            var size = 1;
            if ( this.comboMult > 10 )
            {
                c = 0xFFFFFFFF;
                power = 5;
                size = 1.3;
            }
            else
            {
                c = this.arrColors[jewel.type - 1]; //+  Math.round( Math.random() * 0x050505 );
            }

            var color = Tools.offsetColor( c, Math.random() * 60 - 30 );
            var rad = Math.atan2( iy - this.jewelSize / 2, ix - this.jewelSize / 2 );
            var dist = Math.sqrt( Math.pow( this.jewelSize / 2 - ix, 2 ) + Math.pow( this.jewelSize / 2 - iy, 2 ) );
            this.particlesBubble.createParticle( Math.random() * size, jewel.x + this.jewelSize / 2,
                                                 jewel.y + this.jewelSize / 2,
                                                 new createjs.Point( Math.cos( rad ) * ( Math.random() * dist ) / 5 * power,
                                                                     Math.sin( rad ) * ( Math.random() * dist ) / 5 * power - 5 ),
                                                 color );

            if ( this.comboMult > 10 )
            {
                this.particlesStar.createParticle( jewel.x + this.jewelSize / 2, jewel.y + this.jewelSize / 2, Math.random() * .5 + .3, Math.random() * 360, 2 );
            }

        }
    }

    this.drawCombination = function( c )
    {

        if ( c == null ) return;

        var cbd = new createjs.BitmapData( bd.width, bd.height, true, 0x0 );

        for ( var p in c.jewels )
        {
            cbd.fillRect( new createjs.Rectangle( p.x * this.jewelSize, p.y * this.jewelSize, this.jewelSize, this.jewelSize ), 0xFFFFFFFF );
        }

        cbd.applyFilter( cbd, cbd.rect, new createjs.Point( 0, 0 ), new BlurFilter( 10, 10 ) );
        cbd.applyFilter( cbd, cbd.rect, new createjs.Point( 0, 0 ), new GlowFilter( 0xFFFFFF, 1, 10, 10, 2, 1, true, true ) );

        bd.draw( cbd );

    }

    this.initPowerMeters = function()
    {
        for ( var i = 0; i < this.qtdJewel; i++ )
        {
            this.powerMeters[i] = 0;
        }
    }

    this.addPower = function( c )//:Combination )
    {

        var add = 0;
        //for each( var p:Point in c.jewels )
        for ( var i = 0; i < c.jewels.length; i++ )
        {
            var p = c.jewels[i]
            if ( !this.getJewelAt( p.x, p.y ).infected )
            {
                add++;
            }
        }

        this.powerMeters[c.type - 1] += add;

        while ( this.powerMeters[c.type - 1] >= this.powerLimit )
        {

            //Create PowerJewel
            this.createPowerJewel( c.type );

            //trace( c.type + " POWER" );
            this.powerMeters[c.type - 1] %= this.powerLimit;

        }

    }

    this.findRandomIsolatedJewel = function()//:Point
    {

        if ( this.isolatedJewels.length > 0 )
        {
            return this.isolatedJewels[Math.round( Math.random() * ( this.isolatedJewels.length - 1 ) )];
        }
        else
        {
            return null;
        }

    }

    this.findRandomIsolatedJewelOfType = function( type )//:Point
    {

        var rJewels = new Array();

        for ( var i = 0; i < this.isolatedJewels.length; i++ )
        {
            var p = this.isolatedJewels[i];
            var j = this.getJewelAt( p.x, p.y );
            if ( j.type == type )
            {
                rJewels.push( p );
            }
        }

        if ( rJewels.length > 0 )
        {
            return rJewels[Math.round( Math.random() * ( rJewels.length - 1 ) )];
        }
        else
        {
            return null;
        }

    }

    this.findRandomJewelOfType = function( type )//:Point
    {

        //var rJewels = new Vector.<Point>();
        var rJewels = new Array();

        for ( var i = 0; i < this.tableWidth; i++ )
        {
            for ( var j = 0; j < this.tableHeight; j++ )
            {
                var jewel = this.getJewelAt( i, j );
                if ( jewel == null ) continue;
                if ( jewel.type == type )
                {
                    rJewels.push( new createjs.Point( i, j ) );
                }
            }
        }

        if ( rJewels.length > 0 )
        {
            return rJewels[Math.round( Math.random() * ( rJewels.length - 1 ) )];
        }
        else
        {
            return null;
        }

    }

    this.createPowerJewel = function( type )
    {

        this.findAllCombinations();

        var p = this.findRandomIsolatedJewelOfType( type );
        var powerUp = this.getRandomPowerUpForType( type );
        if ( powerUp == null ) return;
        if ( p != null && Math.random() < .5 )
        {
            this.setJewel( p, type, powerUp );
            GameSounds.playPowerUpCreated();
        }
        else
        {
            this.bufferJewel( type, powerUp );
        }
    }

    this.createTimerJewel = function( p )//( this.p:Point = null )
    {
        this.findAllCombinations();

        var p = p == null ? this.findRandomIsolatedJewel() : p;

        if ( p != null )
        {
            var j = this.getJewelAt( p.x, p.y );
            j.isTimer = true;
            this.createParticlesForJewel( p, 8 );
            j.flash();
            GameSounds.playClockCreated();

            //gl.addLog( GameLog.ACTIONCREATETIMER, {px:p.x, py:p.y} );

        }
        else
        {
            //probably will never endup here...but...
            this.bufferJewel( this.getRandomType(), null, true );
        }
    }

    this.bufferJewel = function( type, powerUp, isTimer )//( type, powerUp, isTimer = false )
    {
        var bj = new BufferJewel();
        bj.init( type, powerUp, isTimer );
        this.dropBuffer.push( bj );
    }

    this.activateJewelSuperPower = function( p, wd )//p:Point, wd:WaveDot = null )
    {

        var j = this.getJewelAt( p.x, p.y );

        if ( j == null || !j.hasSuperPower() ) return;

        var powerWave;
        var params = {};

        params.level = j.powerUp.level;
        //parseInt( myParent["mcHud"].txtStr.text );

        if ( j.superPower >= 1 && j.superPower <= 4 )
        {
            //Unidirecional
            if ( j.superPower == 1 ) params.direction = 1;
            if ( j.superPower == 2 ) params.direction = 2;
            if ( j.superPower == 3 ) params.direction = 3;
            if ( j.superPower == 4 ) params.direction = 4;
            powerWave = new UniDirectional();
        }
        else if ( j.superPower >= 5 && j.superPower <= 6 )
        {
            //Bidirectional
            if ( j.superPower == 5 ) params.isVertical = false;
            if ( j.superPower == 6 ) params.isVertical = true;
            powerWave = new BiDirecional();
        }
        else if ( j.superPower == 7 )
        {
            //Crossed
            powerWave = new Crossed();
        }
        else if ( j.superPower >= 8 && j.superPower <= 11 )
        {
            //L
            if ( j.superPower == 8 ) params.direction = 1;
            if ( j.superPower == 9 ) params.direction = 2;
            if ( j.superPower == 10 ) params.direction = 3;
            if ( j.superPower == 11 ) params.direction = 4;
            powerWave = new LWave();
        }
        else if ( j.superPower >= 12 && j.superPower <= 13 )
        {
            //Spiral
            if ( j.superPower == 12 ) params.direction = 3;
            if ( j.superPower == 13 ) params.direction = 1;
            powerWave = new Spiral();

        }
        else if ( j.superPower == 14 )
        {
            //Magnetic
            powerWave = new MagneticWave();
        }

        powerWave.init( this, j.powerUp, p, params );


        if ( wd != null ) powerWave.mergeDot( wd );
        this.startPowerWave( powerWave );
        j.consumePowerUp();
        this.particlesStar.createParticle( j.x + this.jewelSize / 2, j.y + this.jewelSize / 2, 0, 0, this.starsPerJewel );
        GameSounds.playPowerUp();

    }

    this.startPowerWave = function( powerWave )//:WaveBase )
    {
        //trace( "Start wave!" );
        this.powerWaves.push( powerWave );
    }

    this.setJewel = function( p, type, powerUp, createStars )//( p:Point, type, powerUp = null, createStars = false )
    {
        var j = this.getJewelAt( p.x, p.y );

        if ( j != null )
        {
            j.type = type;

            if ( j.hasSuperPower() )
            {
                j.powerUp.type = j.type;
            }
            if ( powerUp != null )
            {
                j.setPowerUp( powerUp.clone(), p );
            }
            j.infected = true;


            if ( createStars )
            {
                this.particlesStar.createParticle( j.x + this.jewelSize / 2, j.y + this.jewelSize / 2, 0, 0, this.starsPerJewel );
            }
            else
            {
                this.createParticlesForJewel( p, 8 );
            }

            j.flash();

            this.findAllCombinations();

            //gl.addLog( GameLog.ACTIONSETJEWEL, {px: p.x, py: p.y, t:type, sp:j.superPower, spl:j.hasSuperPower ? j.powerUp.level : 0, cs:createStars } );
        }
    }

    this.getRandomPowerUpForType = function( type )//
    {
        var arr = new Array();

        for ( var i = 0; i < this.powerUps.length; i++ )
        {
            var p = this.powerUps[i];
            if ( p.type == type && !p.isOnCooldown() )
            {
                arr.push( p );
            }
        }
        if ( arr.length == 0 ) return null;

        p = arr[Math.floor( Math.random() * arr.length )];
        p.pop();

        return p.clone();

        //return Math.floor( Math.random() * 11 ) + 1; //(1 - 4)			
        //			return Math.round( Math.random() * 3 ) + 9;			
    }

    this.getPowerUpFromSuperPower = function( superPower )//
    {
        if ( superPower == 0 ) return null;

        //for each( var pup in powerUps )
        for ( var pup in powerUps )
        {
            //for each( var sp in pup.superPowers )
            for ( var sp in pup.superPowers )
            {
                if ( sp == superPower )
                {
                    return pup.clone();
                }
            }
        }
        return null;
    }

    this.createSuddenPowerUp = function( bottomOnly, sfx, pregameMode )
    {
        if ( this.state != this.STATE_GAME && !pregameMode ) return;
        bottomOnly = ( bottomOnly == undefined ) ? true : false;
        sfx = ( sfx == undefined ) ? true : false;
        //if( isReplay ) return;
        var rPoint;
        var rndJ;
        var control = 0;
        do
        {
            control++;
            if ( bottomOnly )
            {
                rPoint = new createjs.Point( Math.round( Math.random() * ( this.tableWidth - 3 ) ) + 1, Math.round( this.tableHeight / 2 + Math.random() * ( this.tableHeight / 2 - 1 ) ) );
            }
            else
            {
                rPoint = new createjs.Point( Math.floor( Math.random() * this.tableWidth ), Math.floor( Math.random() * this.tableHeight - 3 ) + 3 );
            }
            rndJ = this.getJewelAt( rPoint.x, rPoint.y );

        } while ( rndJ && rndJ.hasSuperPower() && control < 500 );

        var powerUp = this.getRandomPowerUpForType( rndJ.type );
        if ( powerUp )
        {
            this.setJewel( rPoint, rndJ.type, this.getRandomPowerUpForType( rndJ.type ) );
            if ( sfx ) GameSounds.playPowerUpCreated();
        }
        this.findAllCombinations();

    }

    this.increaseDebuff = function()
    {
        this.scoreDebuff = Math.min( this.scoreDebuff + 1, this.scoreDebuffMax );
        this.scoreDebuffTime = Tools.getNow();
    }

    this.decreaseDebuff = function()
    {
        this.scoreDebuff = Math.max( this.scoreDebuff - 1, 0 );
        this.scoreDebuffTime = Tools.getNow();
    }

    this.increaseSpeedMult = function()
    {
        this.comboMult = Math.min( this.comboMult + 1, 11 );

        this.speedMult++;
        if ( this.speedMult == 10 )
        {
            this.speedMult = 0;
            this.createTimerJewel();
            this.speedBonusInterval = Math.max( this.speedBonusInterval - ( this.speedBonusMaxInterval / 2 ), this.speedBonusMinInterval );
        }

    }

    this.decreaseSpeedMult = function()
    {
        if ( this.comboMult > 10 && this.state != this.STATE_GAMEOVER )
        {
            GameSounds.playComboLost();
        }
        this.comboMult = 0;
        this.speedMult = Math.max( this.speedMult - 3, 0 );
        this.lastCombinationTime = Tools.getNow();
        this.speedBonusInterval = Math.min( this.speedBonusInterval + this.speedBonusMaxInterval / 20, this.speedBonusMaxInterval );
    }

    this.initPowerUps = function()
    {
        this.jt = Images.getImage( Images.JEWELS_TABLE );
        //powerUps = new Vector.<PowerUp>();
        this.powerUps = new Array();
        var iceData = [{ level: 2 }];
        this.icelvl = parseInt( iceData[0].level );
        this.timeBonus = 1000 + ( 1000 * this.icelvl );

        for ( var z = 0; z < this.qtdJewel; z++ )
        {
            var type = z + 1;
            var craftItems = new Array();//inventory.getCraftItemsByType( type.toString() );

            for ( var n = 0; n < 5; n++ )
            {
                craftItems.push( { colorId: n, level: 3 } );
            }

            //for each( var craftItem:InventoryItem in craftItems )
            for ( var i = 0; i < craftItems.length; i++ )
            {
                var craftItem = craftItems[i];
                var color = parseInt( craftItem.colorId ) + 1;
                var level = parseInt( craftItem.level );
                var pu = new PowerUp();
                if ( type == 1 )
                {
                    pu.init( this, color, level, SuperPowerTypes.UNIDIRECTIONAL() );
                    if ( this.jtpUni == null ) this.jtpUni = Images.getImage( Images.JEWELS_UNIDIRETIONAL );
                }
                else if ( type == 2 )
                {
                    pu.init( this, color, level, SuperPowerTypes.SPIRAL() );
                    if ( this.jtpEspiral == null ) this.jtpEspiral = Images.getImage( Images.JEWELS_SPIRAL );
                }
                else if ( type == 3 )
                {
                    pu.init( this, color, level, SuperPowerTypes.L() );
                    if ( this.jtpL == null ) this.jtpL = Images.getImage( Images.JEWELS_L );
                }
                else if ( type == 4 )
                {
                    pu.init( this, color, level, SuperPowerTypes.MAGNETIC() );
                    if ( this.jtpMagnet == null ) this.jtpMagnet = Images.getImage( Images.JEWELS_MAGNET );
                }
                else
                {
                    pu.init( this, color, level, SuperPowerTypes.UNIDIRECTIONAL() );
                }
                /*
                else if ( type == 5 )
                {
                    this.powerUps.push( new PowerUp( this, color, level, SuperPowerTypes.BIDIRECTIONAL() ) );
                }
                else if ( type == 6 )
                {
                    this.powerUps.push( new PowerUp( this, color, level, SuperPowerTypes.CROSSED() ) );
                }*/
                this.powerUps.push( pu );
            }
        }
    }

    this.addJewel = function( j )
    {
        this.jewelsContainer.addChild( j );
    }

    this.removeJewel = function( j )
    {
        if ( j.parent )
        {
            j.destroy();
        }
    }

    this.pause = function()
    {
        if ( this.state != this.STATE_PAUSED )
        {
            this.lastState = this.state;
            this.state = this.STATE_PAUSED;
        }
    }

    this.unpause = function()
    {
        if ( this.state == this.STATE_PAUSED )
        {
            this.state = this.lastState;
        }
    }

    this.destroy = function()
    {
        for ( var y = 0; y < this.tableWidth; y++ )
        {
            for ( var x = 0; x < this.tableHeight; x++ )
            {
                var jewel = this.jewels[x][y];
                if ( jewel ) jewel.destroy();
                this.jewels[x][y] = null
            }
        }

        this.clearMc( this.jewelsContainer );
        this.clearMc( this.particlesContainer );

    }

    this.clearMc = function( mc )
    {
        if ( mc )
        {
            while ( mc.getChildAt( 0 ) )
            {
                mc.removeChildAt( 0 );
            }
        }
    }

    this.saveState = function()
    {
        //TODO
    }

    this.loadState = function( stateData )
    {
        //TODO
    }
} );
