//---------------------------------------------------------------------------
// File: client_experience.cs
//
// This file contains the client-side experience system, which is used to
// update the rendered experience guis that are used to buy experience-
// based features.
//
// Author: Michael Felice
//---------------------------------------------------------------------------

// text color values in the experience system
$ExperienceColorPlus = "0 0 1 1";
$ExperienceColorMinus = "1 0 0 1";
$ExperienceColorSold = "0.2 0.2 0.2 1";

// the number of experience blocks displayed per screen (this
// is automatically figured out by the script)
$ExperiencePerScreen = 0;
$ExperienceIndex = 0;
$ExperienceTab = 0;

// this function is called once per clock tick on the client and is
// used to determine when a message should be sent to the hud because
// and experience block is now available to buy (temporarily removed)
function SLExperienceManager::UpdateMessages(%manager)
{
   /*
   if (isObject(ExperienceManager) == false)
   {
      // this should be handled
      return;
   }
   
   if (isObject(GameResourceStack) == false)
   {
      return;
   }
   
   %gameResource = GameResourceStack.getResource();
   if (isObject(%gameResource) == false)
   {
      return;
   }
   
   for (%tab = 0; %tab < 3; %tab++)
   {
      // check each of the experience blocks in the experience manager
      for (%index = 0; %index < ExperienceManager.getCount(%tab); %index++)
      {
         // get the experience block (if it is sold or the object does
         // not exist, do not check for message rendering)
         %exp = ExperienceManager.getExperience(%tab, %index);
         if (isObject(%exp) == false || %exp.sold == true)
         {
            continue;
         }
         
         // show message is false initially and if the experience could
         // not be bought, set the message to true (when the message moves
         // from true to false, a message is rendered)
         %showMessage = false;
         if (%gameResource.getExperience().getCount() < %exp.expCost) %showMessage = true;
         if (%gameResource.getGold().getCount() < %exp.goldCost) %showMessage = true;
         if (%gameResource.getWood().getCount() < %exp.woodCost) %showMessage = true;
         for (%reqIndex = 0; %reqIndex < $Experience::MaxRequirements; %reqIndex++)
         {
            %desc = %exp.getReqDescription(%reqIndex);
            if (%desc !$= "" && %exp.getReqCheck(%reqIndex) == false) %showMessage = true;
         }

         // if the render message switches from true to false, render the message
         // (do not render the message if it moves from false to true-- this
         // occurs the first time an experience block is initialized for messages)
         if (%exp.showMessage && %showMessage == false)
         {
            SendHudMessage("Unlocked new experience object: " @ %exp.name @ "!");
         }
         
         // update the experience block show message
         %exp.showMessage = %showMessage;
      }
   }
   */
}

// this function is called every time an experience block is chosen to buy
function XPBuy::buttonSelect(%button)
{
   %parent = %button.getParent();
   %index = strreplace(%parent.getName(), "XPWindow", "");
   
   %button.selected = true;

   // inform the server that an experience block was bought
   commandToServer('BuyExperience', $ExperienceTab, %index + $ExperienceIndex);
}

// move to the next page of experience blocks
function XPNext::buttonSelect()
{
   $ExperienceIndex += $ExperiencePerScreen;
   
   clientCmdShowExperience();
}

// move to the previous page of experience blocks
function XPPrev::buttonSelect()
{
   $ExperienceIndex -= $ExperiencePerScreen;
   
   clientCmdShowExperience();
}

// handle the first tab is selected
function XPTab0::buttonSelect()
{
   XPTab0.selected = true;
   XPTab1.selected = false;
   XPTab2.selected = false;

   $ExperienceIndex = 0;
   $ExperienceTab = 0;
   $GameMenuLoaded = false;
   BuyExperience();
}

// the second tab is selected
function XPTab1::buttonSelect()
{
   XPTab0.selected = false;
   XPTab1.selected = true;
   XPTab2.selected = false;

   $ExperienceIndex = 0;
   $ExperienceTab = 1;
   $GameMenuLoaded = false;
   BuyExperience();
}

// the third tab is selected
function XPTab2::buttonSelect()
{
   XPTab0.selected = false;
   XPTab1.selected = false;
   XPTab2.selected = true;

   $ExperienceIndex = 0;
   $ExperienceTab = 2;
   $GameMenuLoaded = false;
   BuyExperience();
}


// when the experience page is removed, this function is called
function CloseExperiencePage()
{
   Canvas.popDialog(ExperienceGui);
   slgRenderWorld(true);
   
   $GameMenuLoaded = false;
   slgStackUnpause();
}

// this function is called every time the user decides to enter the
// experience block buying screen
function BuyExperience(%location)
{
   // if the game menu is already loaded, exit
   if ($GameMenuLoaded == true)
   {
      return;
   }
   
   $CanCancelMenu = true;
   
   // clear any existing command states
   csClearTargetState();
   
   // pause the game (but we want to make sure that we maintain the
   // stack level, which works here because the experience buying
   // page is always the first page, never a second page)
   slgStackUnpause();
   slgStackPause();
   
   // update the experience page
   slgRenderWorld(false);
   $GameMenuLoaded = true;
   Canvas.popDialog(ExperienceGui);
   Canvas.pushDialog(ExperienceGui);
   
   // determine how many experience blocks can be displayed on
   // the screen at any given time
   $ExperiencePerScreen = 0;
   %xpwindow = XPWindow @ $ExperiencePerScreen;
   while (isObject(ExperienceGui.getChild(%xpwindow)) == true)
   {
      $ExperiencePerScreen++;
      %xpwindow = XPWindow @ $ExperiencePerScreen;
   }
   
   // ensure that one of the tabs has been selected
   %tabSelected = 0;
   %tabObject = XPTab @ %tabSelected;
   while (isObject(XPTabs.getChild(%tabObject)) == true)
   {
      %object = XPTabs.getChild(%tabObject);
      if (%object.selected == true)
      {
         %tabSelected = -1;
         break;
      }
      
      %tabSelected++;
      %tabObject = XPTab @ %tabSelected;
   }

   // if a tab has not been selected, set the first tab as the
   // default tab that will be selected   
   if (%tabSelected > -1 && isObject(XPTab0) == true)
   {
      XPTab0.selected = true;
   }

   // see if there is a location that the page should jump to
   // when the experience is bought   
   if (%location !$= "")
   {
      $ExperienceTab = getWord(%location, 0);
      %index = getWord(%location, 1);
      
      // select the tab that will be used
      %tab = 0;
      $ExperienceIndex = 0;
      while (isObject(XPTab @ %tab) == true)
      {
         %object = nameToId(XPTab @ %tab);
         if (%tab == $ExperienceTab) %object.selected = true;
         else %object.selected = false;
         
         %tab++;
      }
      
      $ExperienceIndex = %index / $ExperiencePerScreen;

      // ensure that the experience index is a whole number
      %lowCheck = 1;
      while (true)
      {
         if ($ExperienceIndex < %lowCheck)
         {
            $ExperienceIndex = %lowCheck - 1;
            break;
         }
         
         %lowCheck++;
      }
      
      // after experience index is a whole number, find which index
      // to start at (which page to start at based on how many experience
      // blocks are on a screen)
      $ExperienceIndex = $ExperienceIndex * $ExperiencePerScreen;
   }
   
   // notify the server that the experience blocks need to be
   // updated for display
   commandToServer('UpdateExperience');
}

// once the server has update the experience blocks for rendering, the
// client is notified to show the experience page (this function sets
// the content to the experience gui and updates all of the experience
// blocks on the currenct experience block page for rendering purposes)
function clientCmdShowExperience()
{
   Canvas.popDialog(ExperienceGui);
   Canvas.pushDialog(ExperienceGui);
   
   if (isObject(GameResourceStack) == false)
   {
      return;
   }
   
   %gameResource = GameResourceStack.getResource();
   if (isObject(%gameResource) == false)
   {
      return;
   }

   // update each experience block on screen
   for (%index = 0; %index < $ExperiencePerScreen; %index++)
   {
      %expIndex = %index + $ExperienceIndex;
      
      // get the experience block we are loading from
      %exp = ExperienceManager.getExperience($ExperienceTab, %expIndex);
      %window = ExperienceGui.getChild(XPWindow @ %index);
      
      // if we are at the end of the page
      if (isObject(%exp) == false)
      {
         %window.visible = false;
         continue;
      }
      
      // ad this point, the experience block window is visible
      %window.visible = true;
      %buy = true;
      
      // check the sold image
      %isSold = false;
      %sold = %window.getChild(XPSold);
      if (isObject(%sold) == true)
      {
         %sold.visible = %exp.sold;
         if (%sold.visible == true)
         {
            %buy = false;
            %isSold = true;
         }
      }
      
      // check the displayed text name
      %name = %window.getChild(XPName);
      if (isObject(%name) == true)
      {
         %name.stateUp = %exp.name;
         %name.disabled = %exp.hideName;
      }
      
      // check the displayed item image
      %image = %window.getChild(XPImage);
      if (isObject(%image) == true)
      {
         %image.stateUp = %exp.image;
         %image.disabled = %exp.hideImage;
      }
      
      // check the displayed text description
      %description = %window.getChild(XPDescription);
      if (isObject(%description) == true)
      {
         %description.stateUp = %exp.desc;
         %description.disabled = %exp.hideDesc;
      }
      
      // check the displayed lock image
      %locked = %window.getChild(XPLock);
      if (isObject(%locked) == true)
      {
         %locked.visible = %exp.locked;
      }
      
      // check the displayed experience icon
      %experienceIcon = %window.getChild(XPExperienceIcon);
      if (isObject(%experienceIcon) == true)
      {
         if (%exp.expCost <= 0) %experienceIcon.visible = false;
         else %experienceIcon.visible = true;
      }
      
      // check the experience text and check box
      %experienceText = %window.getChild(XPExperienceText);
      %experienceCheck = %window.getChild(XPExperienceCheck);
      if (isObject(%experienceText) == true)
      {
         if (%exp.expCost <= 0) %experienceText.visible = false;
         else %experienceText.visible = true;
         if (isObject(%experienceCheck) == true)
         {
            %experienceCheck.visible = %experienceText.visible && !%isSold;
         }
         %experienceText.stateUp = %exp.expCost;
         %experienceText.disabled = %exp.hideExp;
         
         if (%gameResource.getExperience().getCount() < %exp.expCost)
         {
            %buy = false;
            %experienceText.color = $ExperienceColorMinus;
            if (isObject(%experienceCheck)) %experienceCheck.disabled = true;
         }
         else
         {
            %experienceText.color = $ExperienceColorPlus;
            if (isObject(%experienceCheck)) %experienceCheck.disabled = false;
         }

         if (%isSold == true) %experienceText.color = $ExperienceColorSold;
      }
      
      // check the displayed gold icon
      %goldIcon = %window.getChild(XPGoldIcon);
      if (isObject(%goldIcon) == true)
      {
         if (%exp.goldCost <= 0) %goldIcon.visible = false;
         else %goldIcon.visible = true;
      }
      
      // check the gold text and check box
      %goldText = %window.getChild(XPGoldText);
      %goldCheck = %window.getChild(XPGoldCheck);
      if (isObject(%goldText) == true)
      {
         if (%exp.goldCost <= 0) %goldText.visible = false;
         else %goldText.visible = true;
         if (isObject(%goldCheck) == true)
         {
            %goldCheck.visible = %goldText.visible && !%isSold;
         }
         %goldText.stateUp = %exp.goldCost;
         %goldText.disabled = %exp.hideGold;
         
         if (%gameResource.getGold().getCount() < %exp.goldCost)
         {
            %buy = false;
            %goldText.color = $ExperienceColorMinus;
            if (isObject(%goldCheck)) %goldCheck.disabled = true;
         }
         else
         {
            %goldText.color = $ExperienceColorPlus;
            if (isObject(%goldCheck)) %goldCheck.disabled = false;
         }
         
         if (%isSold == true) %goldText.color = $ExperienceColorSold;
      }
      
      // check the displayed wood icon
      %woodIcon = %window.getChild(XPWoodIcon);
      if (isObject(%woodIcon) == true)
      {
         if (%exp.woodCost <= 0) %woodIcon.visible = false;
         else %woodIcon.visible = true;
      }
      
      // check the wood text and check box
      %woodText = %window.getChild(XPWoodText);
      %woodCheck = %window.getChild(XPWoodCheck);
      if (isObject(%woodText) == true)
      {
         if (%exp.woodCost <= 0) %woodText.visible = false;
         else %woodText.visible = true;
         if (isObject(%woodCheck) == true)
         {
            %woodCheck.visible = %woodText.visible && !%isSold;
         }
         %woodText.stateUp = %exp.woodCost;
         %woodText.disabled = %exp.hideWood;
         
         if (%gameResource.getWood().getCount() < %exp.woodCost)
         {
            %buy = false;
            %woodText.color = $ExperienceColorMinus;
            if (isObject(%woodCheck)) %woodCheck.disabled = true;
         }
         else
         {
            %woodText.color = $ExperienceColorPlus;
            if (isObject(%woodCheck)) %woodCheck.disabled = false;
         }
         
         if (%isSold == true) %woodText.color = $ExperienceColorSold;
      }
      
      // update the experience block rendering for each of the requimrents
      for (%reqIndex = 0; %reqIndex < $Experience::MaxRequirements; %reqIndex++)
      {
         %requirement = %window.getChild(XPRequirement @ %reqIndex);
         if (isObject(%requirement) == true)
         {
            if (%exp.getReqDescription(%reqIndex) $= "") %requirement.visible = false;
            else %requirement.visible = true;
            %requirement.stateUp = %exp.getReqDescription(%reqIndex);
            %requirement.disabled = %exp.getHiddenDescription(%reqIndex);
         }
         
         %check = %window.getChild(XPCheck @ %reqIndex);
         if (isObject(%check) == true)
         {
            %description = %exp.getReqDescription(%reqIndex);
            
            if (%exp.getReqDescription(%reqIndex) $= "") %check.visible = false;
            else %check.visible = true;
            %check.disabled = !%exp.getReqCheck(%reqIndex);
            
            if (%check.disabled == true && %check.visible == true)
            {
               %requirement.color = $ExperienceColorMinus;
               %buy = false;
            }
            else
            {
               %requirement.color = $ExperienceColorPlus;
            }
            
            if (%isSold == true) %requirement.color = $ExperienceColorSold;
         }
      }
      
      // update the buy button after everything else has been
      // rendered (and check if the button should be shown)
      %buyButton = %window.getChild(XPBuy);
      if (isObject(%buyButton) == true)
      {
         %buyButton.disabled = !%buy;
         %buyButton.selected = %isSold;
      }
   }
   
   // set up the previous page button
   %prev = ExperienceGui.getChild(XPPrevHud);
   if (isObject(%prev) == true)
   {
      %prevButton = $ExperienceIndex != 0;
      %prev.visible = %prevButton;
   }
   
   // set up the next page button
   %next = ExperienceGui.getChild(XPNextHud);
   if (isObject(%next) == true)
   {
      %nextButton = $ExperienceIndex + $ExperiencePerScreen < ExperienceManager.getCount($ExperienceTab);
      %next.visible = %nextButton;
   }
}

function clientCmdClearExperience()
{
   for (%tab = 0; %tab < 3; %tab++)
   {
      %size = ExperienceManager.getCount(%tab);
      for (%index = 0; %index < %size; %index++)
      {
         %block = ExperienceManager.getExperience(%tab, %index);
         %object = nameToId(%block.object);
         if (isObject(%object) == true)
         {
            %object.xpCheck = %tab @ " " @ %index;
            commandToServer('SaveXPCheck', %tab, %index, %object.xpCheck);
         }
      }
   }
}

function clientCmdXPBuyObject(%objectName)
{
   %object = nameToId(%objectName);
   if (isObject(%object) == true)
   {
      %tab = getWord(%object.xpCheck, 0);
      %index = getWord(%object.xpCheck, 1);
      %object.xpCheck = "";
      commandToServer('SaveXPCheck', %tab, %index, %object.xpCheck);
   }
}

function clientCmdLoadXPCheck(%objectName, %tab, %index, %xpCheck)
{
   %object = nameToId(%objectName);
   if (isObject(%object) == true)
   {
      %object.xpCheck = %xpCheck;
   }
}
