function PipeMinigame::onWake(%this)
{
   exec("~/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/PipeConfig.cs");

   %x0 = getWord(PipeMinigame.boardPos, 0);
   %y0 = getWord(PipeMinigame.boardPos, 1);
   %pipeSize = PipeMinigame.pipeSize;

   %extent = %pipeSize SPC %pipeSize;

   %i = 0;
   while (true)
   {
      %row = %this.getFieldValue("row"@%i); 
      if (%row $= "")
         break;
      
      %count = getWordCount(%row);
      for (%j = 0; %j < %count; %j++)
      {
         %p = getWord(%row, %j);
         %pieceType = (getSubStr(%p,0,1) $= "p"? "pipe" : "corner");
         %angle = -90*getSubStr(%p,3,1);
         %pieceFile = %pieceType@getSubStr(%p,1,1);
         
         %pos = (%x0 + %j*%pipeSize) SPC (%y0 + %i*%pipeSize);

         if (isFile("~/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%pieceType@"_glow.png"))
         {      
            %pieceGlow = new GuiPlasticBitmapCtrl(){
               canSaveDynamicFields = "0";
               Enabled = "1";
               isContainer = "0";
               Profile = "GuiContentProfile";
               HorizSizing = "relative";
               VertSizing = "relative";
               Position = %pos;
               Extent = %extent;
               MinExtent = "2 2";
               canSave = "1";
               Visible = "1";
               hovertime = "1000";
               alpha = "0";
               color = "255 255 255 255";
               unitClip = "0 0 1 1";
               useVariable = "0";
               tile = "0";      
               rotation = %angle;
               deltaRotation = "0";
               noClip = "0";
               wrap = "0";
               DML = "~/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%pieceType@"_glow.png";
            };
         }
         else
            %pieceGlow = "";

         %this.pieceMat[%i, %j] = new GuiPlasticBitmapCtrl(){
            canSaveDynamicFields = "1";
            Enabled = "1";
            isContainer = "0";
            Profile = "GuiContentProfile";
            HorizSizing = "relative";
            VertSizing = "relative";
            Position = %pos;
            Extent = %extent;
            MinExtent = "2 2";
            canSave = "1";
            Visible = "1";
            hovertime = "1000";
            alpha = "1";
            color = "255 255 255 255";
            unitClip = "0 0 1 1";
            useVariable = "0";
            tile = "0";      
            rotation = %angle;
            deltaRotation = "0";
            noClip = "0";
            wrap = "0";
            DML = "~/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%pieceFile@".png";
               file = %pieceFile;
               type = getSubStr(%p,0,1);
               glow = %pieceGlow;
               next = "";
               prev = "";
         };
         
         MinigameRefCenter.add(%this.pieceMat[%i, %j]);         
         MinigameRefCenter.add(%pieceGlow);         

         %this.pieceBtMat[%i, %j] = new GuiBitmapButtonCtrl() {
            canSaveDynamicFields = "1";
            Enabled = "1";
            className = "PipePieceButton";
            isContainer = "0";
            HorizSizing = "relative";
            VertSizing = "relative";
            Position = %pos;
            Extent = %extent;
            MinExtent = "2 2";
            canSave = "1";
            Visible = "1";
            hovertime = "1000";
            alpha = "1";
            color = "255 255 255 255";
            unitClip = "0 0 1 1";
            lockMouse = "0";
            groupNum = "-1";
            buttonType = "PushButton";
            useMouseEvents = "1";
            bitmap = "";
            command = "PipeMinigame.clickedAt("@%i@","@%j@");";
         };
     }
      
      %i++;
   }

   %this.numOfRows = %i;
   %this.numOfCols = %j;

   %this.twister = new GuiBitmapCtrl() {
      canSaveDynamicFields = "0";
      Enabled = "1";
      isContainer = "0";
      HorizSizing = "relative";
      VertSizing = "relative";
      Position = %this.pieceMat[0,0].getPosition();
      Extent =  %this.pieceMat[0,0].getExtent();
      MinExtent = "2 2";
      canSave = "1";
      Visible = "1";
      hovertime = "1000";
      alpha = "1";
      color = "255 255 255 255";
      unitClip = "0 0 1 1";
      bitmap = "scriptsAndAssets/data/ui/minigame/pipe/twister";
      wrap = "0";
   };
   
   MinigameRefCenter.add(%this.twister);
   
   for (%i = 0; %i < %this.numOfRows; %i++) 
      for (%j = 0; %j < %this.numOfCols; %j++) 
         MinigameRefCenter.add(%this.pieceBtMat[%i, %j]);   

   MinigameRefCenter.pushToBack(PipeExitButton);

   %this.rotationSound = new SFXProfile()
   {
      filename = "scriptsAndAssets/data/ui/minigame/pipe/rotation_sound";
      description = "AudioGui";
      preload = true;
   };

   %this.gameFinished = false;
   
   PipeMinigame.initSpecificGui();

   // Force resizing
   %this.setExtent(getWord(Canvas.extent,0), getWord(Canvas.extent,1));
   Canvas.setWidescreen(MinigameRefCenter, 0, false);
}

// Callback for resizing events
function PipeMinigame::onResize(%this, %width, %height)
{
   Canvas.setWidescreen(MinigameRefCenter, 2000, true);
   
   if (!PipeMinigame.ConfettiIsPlaying)
   {
      onLoseFocus();
      onGainFocus();
      onResumeAfterLosingFocus();
   }
}

function PipeMinigame::start(%this)
{
   %this.onStart();
   
   %this.glow = true;
   %this.activeImage = 1; // 1 or 2
   %this.glowAlpha = 0.05;
   scheduleObjLCA(%this, "Minigame", 100, "animActive", 0);
}

function PipeMinigame::animActive(%this)
{
   if (!%this.glow)
      return;
   
   %this.glowAlpha += 0.1;
   
   if (%this.glowAlpha > 1)
      %this.glowAlpha = -0.95;

   
   for (%iterPos = %this.nextPiece(%this.first); %iterPos !$= ""; %iterPos = %this.nextPiece(%iterPos))
   {
      %piece = %this.getPieceAtIterPos(%iterPos);
      if (%piece.glow !$= "")
         %piece.glow.setAlpha(mAbs(%this.glowAlpha));

      %piece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%piece.file@"_active"@%this.activeImage@".png");
   }
   
   for (%iterPos = %this.nextPiece(%this.last); %iterPos !$= ""; %iterPos = %this.nextPiece(%iterPos))
   {
      %piece = %this.getPieceAtIterPos(%iterPos);
      if (%piece.glow !$= "")
         %piece.glow.setAlpha(mAbs(%this.glowAlpha));

      %piece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%piece.file@"_active"@%this.activeImage@".png");
   }

   if (%this.activeImage == 1)
      %this.activeImage = 2;
   else
      %this.activeImage = 1;

   scheduleObjLCA(%this, "Minigame", 200, "animActive", 0);
}

//Next piece of a connected pipes sequence, use "i j" to start a new interation from that piece
function PipeMinigame::nextPiece(%this, %iterPos)
{
   if (getWordCount(%iterPos) < 4)
      return "-1 -1" SPC %iterPos;
   
   %nextConn = %this.getOtherConnection(getWord(%iterPos, 2), getWord(%iterPos, 3), 
                                        getWord(%iterPos, 0), getWord(%iterPos, 1));
                                        
   if (%nextConn $= "")
      return "";
      
   return getWord(%iterPos, 2) SPC getWord(%iterPos, 3) SPC %nextConn;
}

function PipeMinigame::getPieceAtIterPos(%this, %iterPos)
{
   return %this.pieceMat[getWord(%iterPos, 2), getWord(%iterPos, 3)];
}


function PipeMinigame::clickedAt(%this, %i, %j)
{
   if (%this.curAnim !$= "" && !%this.gameFinished)
      return;
   
   //do not rotate first and last piece   
   if (%this.first $= (%i SPC %j) || %this.last $= (%i SPC %j))
      return;
      
   %piece = %this.pieceMat[%i, %j];
   
   //don't glow pieces from the clicked piece (sequence from first)
   %found = false;
   for (%iterPos = %this.nextPiece(%this.first); %iterPos !$= ""; %iterPos = %this.nextPiece(%iterPos))
   {
      %glPiece = %this.getPieceAtIterPos(%iterPos);
      if (%piece == %glPiece)
         %found = true;
      
      if (%found)   
      {
         if (%glPiece.glow !$= "")
            %glPiece.glow.setAlpha(0);

         %glPiece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%glPiece.file@".png");
      }
   }
   
   //don't glow pieces from the clicked piece (sequence from last)
   %found = false;
   for (%iterPos = %this.nextPiece(%this.last); %iterPos !$= ""; %iterPos = %this.nextPiece(%iterPos))
   {
      %glPiece = %this.getPieceAtIterPos(%iterPos);
      if (%piece == %glPiece)
         %found = true;
      
      if (%found)   
      {
         if (%glPiece.glow !$= "")
            %glPiece.glow.setAlpha(0);
            
         %glPiece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%glPiece.file@".png");
      }
   }

   %piece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%piece.file@"_twist.png");

   sfxPlay(%this.rotationSound);
 
   %this.curAnim = %piece.rotation SPC %piece SPC 0;
   scheduleObjLCA(%this, "Minigame", 10, "animRotation", 0);
}

function PipeMinigame::animRotation(%this)
{
   %angle = getWord(%this.curAnim, 0);  
   %piece = getWord(%this.curAnim, 1);  
   %step = getWord(%this.curAnim, 2) + 1;  

   %piece.rotation = %angle - 90*(%step/PipeMinigame.stepsPerRotation); 
   
   if (%piece.rotation == -360)
      %piece.rotation = 0;
      
   %piece.glow.rotation = %piece.rotation;
   
   if (%step < PipeMinigame.stepsPerRotation)
   {
      %this.curAnim = setWord(%this.curAnim, 2, %step);
      scheduleObjLCA(%this, "Minigame", 100, "animRotation", 0);
   }
   else
   {
      %piece.setDML("scriptsAndAssets/data/ui/minigame/pipe/"@playMinigameDlg.currentLevel@"/"@%piece.file@".png");
      
      %this.curAnim = "";
      
      //check victory
      for (%iterPos = %this.nextPiece(%this.first); %iterPos !$= ""; %iterPos = %this.nextPiece(%iterPos))
         if (%this.getPieceAtIterPos(%iterPos) == %this.pieceMat[getWord(%this.last,0), getWord(%this.last,1)])
         {
            %this.gameFinished = true;
            scheduleObjLCA(%this, "Minigame", 200, "quit", 0);
            break;
         }
   }
}

//give a pipe %i %j, connected to %connI %connJ, get the other connection it has.
function PipeMinigame::getOtherConnection(%this, %i, %j, %connI, %connJ)
{
   %conns = %this.getConnections(%i, %j);
   
   if (%conns $= "")
      return "";
   
   %otI = getWord(%conns, 0);
   %otJ = getWord(%conns, 1);
   
   //check if this is the other
   if (%otI != %connI || %otJ != %connJ)
      return %otI SPC %otJ;   

   if (getWordCount(%conns) < 4)
      return "";   
   
   %otI = getWord(%conns, 2);
   %otJ = getWord(%conns, 3);
   
   //check if this is the other
   if (%otI != %connI || %otJ != %connJ)
      return %otI SPC %otJ;   
   
   return "";
}

//get connections of the pipe (adjacent pieces that really matches with %i %j)
function PipeMinigame::getConnections(%this, %i, %j)
{
   %adjPieces = %this.getPipeAdjPieces(%i, %j);
   
   %i1 = getWord(%adjPieces, 0);
   %j1 = getWord(%adjPieces, 1);
   %i2 = getWord(%adjPieces, 2);
   %j2 = getWord(%adjPieces, 3);

   %conns = "";

   %adjPieces = %this.getPipeAdjPieces(%i1, %j1);
   
   if ((%i == getWord(%adjPieces, 0) && %j == getWord(%adjPieces, 1))
       || (%i == getWord(%adjPieces, 2) && %j == getWord(%adjPieces, 3)))
      %conns = %i1 SPC %j1;
   
   %adjPieces = %this.getPipeAdjPieces(%i2, %j2);
   
   if ((%i == getWord(%adjPieces, 0) && %j == getWord(%adjPieces, 1))
       || (%i == getWord(%adjPieces, 2) && %j == getWord(%adjPieces, 3)))
      %conns = (%conns $= ""? "" : %conns@" ")@ %i2 SPC %j2;
      
   return %conns;
}

//get pieces adjacent to the pipe terminations.
function PipeMinigame::getPipeAdjPieces(%this, %i, %j)
{
   if (%i < 0 || %i >=  %this.numOfRows || %j < 0 || %j >= %this.numOfCols)
      return "-1 -1 -1 -1";
   
   %piece = %this.pieceMat[%i, %j];
   
   if (%piece.type $= "p")
   {
      if (%piece.rotation == 0 || %piece.rotation == -180)
      {
         return %i SPC (%j - 1) SPC %i SPC (%j + 1);
      }
      else if (%piece.rotation == -90 || %piece.rotation == -270)
      {
         return (%i - 1) SPC %j SPC (%i + 1) SPC %j;
      }
   }
   else
   {
      if (%piece.rotation == 0)
      {
         return (%i + 1) SPC %j SPC %i SPC (%j + 1);
      }
      else if (%piece.rotation == -90)
      {
         return %i SPC (%j - 1) SPC (%i + 1) SPC %j;
      }
      else if (%piece.rotation == -180)
      {
         return %i SPC (%j - 1) SPC (%i - 1) SPC %j;
      }
      else if (%piece.rotation == -270)
      {
         return (%i - 1) SPC %j SPC %i SPC (%j + 1);
      }
   }

   return "-1 -1 -1 -1";
}

// Quit minigame
function PipeMinigame::quit(%this)
{
   %this.glow = false;
   sfxStopAll();
   
   lockMouse(false);
   Canvas.showCursor();            
   
   // Widescreen support
   if(isObject(MinigameCenter))
   {
      Minigame.bringToFront(%this);
      MinigameCenter.setVisible(true);
      Minigame.pushToBack(MinigameCenter);   
   }   
   
   // Number of hints won
   Minigame.hintsGained = %this.meter.getHintsGained();    
   
   %this.meter.pause = true;
   %this.counter.pause = true;
   
   if(mFloor(Minigame.hintsGained) > 0 && %this.gameFinished /*&& PlayMinigameDlg.isPlayingMinigame !$= true*/)
   {      
      if(!%this.ConfettiIsPlaying)
      {
         if(isObject(PlayMinigameDlg))
         {            
            PlayMinigameDlgCenter.pushToBack(MinigameCircles);
            PlayMinigameDlgCenter.pushToBack(MinigameParticleFx);
            PlayMinigameDlgCenter.pushToBack(WinText);
            PlayMinigameDlgCenter.pushToBack(HintNumber);
            PlayMinigameDlgCenter.pushToBack(PMClapper);
            PlayMinigameDlgCenter.pushToBack(PMBoard);
            PlayMinigameDlgCenter.pushToBack(PMClapperStart);   
                     
            PlayMinigameDlg.bringToFront(%this);
            
            PlayMinigameDlg.setVisible(true);            
            PlayMinigameDlgCenter.setVisible(true);
         }
            
         // Play confetti
         MinigameParticleFx.ConfettiFx(15); // Play confetti for 15 secs
         %this.ConfettiIsPlaying = true;
         
         if(PlayMinigameDlg.isPlayingMinigame $= true)
            scheduleObjLCA(playMinigameDlg, "Minigame", 15*1000, "quitMinigame", 0);
         else
            // Quit a bit earlier
            scheduleObjLCA(playMinigameDlg, "Minigame", 12*1000, "quitMinigame", 0);
      }
   }
   else
   {
      Minigame.hintsGained = 0;
      
      if(isObject(PlayMinigameDlg))
         PlayMinigameDlg.bringToFront(PlayMinigameDlg.curMinigame);
      
      playMinigameDlg.quitMinigame();
   }
}

//function PipeMinigame::onMouseMove(%this, %modifier, %worldPosition, %mouseClicks )
//{
   //%x = getWord(%worldPosition, 0) - getWord(PipeMinigame.boardPos, 0);
   //%y = getWord(%worldPosition, 1) - getWord(PipeMinigame.boardPos, 1);
   //
   //%j = mFloor(%x / PipeMinigame.pipeSize);
   //%i = mFloor(%y / PipeMinigame.pipeSize);
 //
   //if (%i < %this.numOfRows && %j < %this.numOfCols)
   //{
      //%pos = %this.pieceMat[%i, %j].getPosition();    
      //%this.twister.setPosition(getWord(%pos, 0), getWord(%pos, 1));
   //}
   //
//}

function PipePieceButton::onMouseEnter(%this)
{
   %pos = %this.getPosition();
   if (%pos $= PipeMinigame.pieceBtMat[getWord(PipeMinigame.first, 0), getWord(PipeMinigame.first, 1)].getPosition()
       || %pos $= PipeMinigame.pieceBtMat[getWord(PipeMinigame.last, 0), getWord(PipeMinigame.last, 1)].getPosition())
       {
          PipeMinigame.twister.setVisible(false);
       }
   else
   {
      PipeMinigame.twister.setVisible(true);
      PipeMinigame.twister.setPosition(getWord(%pos, 0), getWord(%pos, 1));
   }
}

function PipeSkipButton::onMouseEnter(%this){
   %this.setBitmap("scriptsAndAssets/data/ui/minigame/skip_rollover.png");
}

function PipeSkipButton::onMouseLeave(%this){
   %this.setBitmap("scriptsAndAssets/data/ui/minigame/skip.png");
}

function PipeSkipButton::onMouseDown(%this){
   %this.setBitmap("scriptsAndAssets/data/ui/minigame/skip_pressed.png");
}
