//------------------------------------------------------------
// Copyright Sandlot Games, 2007
// author: Michael Felice
// file: client_questGui.cs
// brief:
//    This quest page that appears in the screen when specific
// quest information is gathered.  All quest update calls
// should be made through three functions in this file,
// named CreateQuest, CreateQuestTask, and CompleteQuestTask.
// The quest hud information will automatically be updated
// based on how the quest page changes.  Note that
// StartQuestGui and ExitQuestGui can also be called to
// respectively load the quest screen and close the quest
// screen.
//------------------------------------------------------------

$QuestRequiredCount = 0;
$QuestRequiredData = 0;
$QuestOptionalCount = 0;
$QuestOptionalData = 0;
$QuestShowInfo = 0;

// quest icon positioning based on screen resolution
$QuestIconPos_800x600 = "285 -1";
$QuestIconPos_1024x768 = "365 -2";
$QuestIconPos_1280x768 = "455 -2";
$QuestIconPos_1280x800 = "455 -2";

// clears any existing information that will be filled in shortly
function InitializeQuestGui()
{
   ClearQuests();
   
   if (isObject($QuestShowInfo))
   {
      HideQuest($QuestShowInfo);
   }
   
   // remove all of the required quests
   for (%index = 0; %index < $QuestRequiredCount; %index++)
   {
      %check = $QuestRequiredData[%index, 0];
      %check.delete();
      
      %title = $QuestRequiredData[%index, 1];
      if (isObject(%title.strike) == true)
      {
         %title.strike.delete();
      }
      if (isObject(%title.complete) == true)
      {
         %title.complete.delete();
      }
      RemoveQuest(%title.textDown);
      %title.delete();
   }
   
   // remove all of the optional quests
   for (%index = 0; %index < $QuestOptionalCount; %index++)
   {
      %check = $QuestOptionalData[%index, 0];
      %check.delete();
      
      %title = $QuestOptionalData[%index, 1];
      if (isObject(%title.strike) == true)
      {
         %title.strike.delete();
      }
      if (isObject(%title.complete) == true)
      {
         %title.complete.delete();
      }
      RemoveQuest(%title.textDown);
      %title.delete();
   }
      
   $QuestRequiredCount = 0;
   $QuestRequiredData = 0;
   $QuestOptionalCount = 0;
   $QuestOptionalData = 0;
   $QuestShowInfo = 0;
   
   DestroyHudQuests();
   InitHudQuests();
}

// adds the quest gui
function StartQuestGui()
{
   // if the game menu is already loaded, exit
   if ($GameMenuLoaded == true)
   {
      return;
   }
   
   // clear any existing command states
   csClearTargetState();
   
   slgStackPause();
   Canvas.pushDialog(QuestScreenGui);
   slgRenderWorld(false);
   
   if ($QuestShowInfo != 0)
   {
      ShowQuest($QuestShowInfo);
   }
   
   $GameMenuLoaded = true;
}

// exits the quest gui
function ExitQuestGui()
{
   Canvas.popDialog(QuestScreenGui);
   slgStackUnpause();
   
   slgRenderWorld(true);
   
   $GameMenuLoaded = false;
}

// returns the position of the required quest check box at
// the index specified
function GetRequiredCheckPosition(%index)
{
   %beginTitle = QuestRequiredList.getChild(BeginQuestCheck);
   %nextTitle = QuestRequiredList.getChild(NextQuestCheck);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(%nextTitle.position, 0) - %posX;
   %diffY = getWord(%nextTitle.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

// returns the position of the required quest title text at
// the index specified
function GetRequiredTitlePosition(%index)
{
   %beginTitle = QuestRequiredList.getChild(BeginQuestTitle);
   %nextTitle = QuestRequiredList.getChild(NextQuestTitle);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(%nextTitle.position, 0) - %posX;
   %diffY = getWord(%nextTitle.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

// returns the position of the optional quest check box at
// the index specified
function GetOptionalCheckPosition(%index)
{
   %beginTitle = QuestOptionalList.getChild(BeginQuestCheck);
   %nextTitle = QuestOptionalList.getChild(NextQuestCheck);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(%nextTitle.position, 0) - %posX;
   %diffY = getWord(%nextTitle.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

// returns the position of the optional quest title text at
// the index specified
function GetOptionalTitlePosition(%index)
{
   %beginTitle = QuestOptionalList.getChild(BeginQuestTitle);
   %nextTitle = QuestOptionalList.getChild(NextQuestTitle);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(%nextTitle.position, 0) - %posX;
   %diffY = getWord(%nextTitle.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

// returns the position of the long description check box
// given the index of the long description
function GetLongCheckPosition(%index)
{
   %posX = getWord(BeginQuestTaskCheck.position, 0);
   %posY = getWord(BeginQuestTaskCheck.position, 1);
   %diffX = getWord(NextQuestTaskCheck.position, 0) - %posX;
   %diffY = getWord(NextQuestTaskCheck.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

// returns the position of the long description text box
// given the index of the long description
function GetLongTextPosition(%index)
{
   %posX = getWord(BeginQuestTaskLong.position, 0);
   %posY = getWord(BeginQuestTaskLong.position, 1);
   %diffX = getWord(NextQuestTaskLong.position, 0) - %posX;
   %diffY = getWord(NextQuestTaskLong.position, 1) - %posY;
   
   return %posX + %index * %diffX @ " " @ %posY + %index * %diffY;
}

function GetStrikePositionDiff()
{
   %beginTitle = QuestRequiredList.getChild(BeginQuestTitle);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(StrikeQuest.position, 0) - %posX;
   %diffY = getWord(StrikeQuest.position, 1) - %posY;
   
   return %diffX @ " " @ %diffY;
}

function GetCompletePositionDiff()
{
   %beginTitle = QuestRequiredList.getChild(BeginQuestTitle);
   %posX = getWord(%beginTitle.position, 0);
   %posY = getWord(%beginTitle.position, 1);
   %diffX = getWord(CompleteQuest.position, 0) - %posX;
   %diffY = getWord(CompleteQuest.position, 1) - %posY;
   
   return %diffX @ " " @ %diffY;
}

// updates scrollbar information (call this when the long task
// description information changes-- this will determine how
// much the scrollbar should scroll or if it shouldn't scroll)
function UpdateQuestControlScrollExtent(%count)
{
   %height = getWord(GetLongTextPosition(%count - 1), 1) + getWord(NextQuestTaskLong.extent, 1);
   %height2 = getWord(GetLongCheckPosition(%count - 1), 1) + getWord(NextQuestTaskCheck.extent, 1);
   if (%height2 > %height) %height = %height2;
   
   // start by turning off the scroll bar entirely
   QuestScrollControl.extent = BaseQuestScrollControl.extent;
   BaseQuestScrollControl.vScrollBar = "alwaysOff";
   
   // check if the scroll bar should scroll
   if (%height > getWord(BaseQuestScrollControl.extent, 1))
   {
      // update the scroll bar dimensions for how far it should scroll
      %margin = getWord(NextQuestTaskCheck.position, 1) -
         getWord(BeginQuestTaskCheck.position, 1) -
         getWord(NextQuestTaskCheck.extent, 1);

      %width = getWord(QuestScrollControl.extent, 0);
      QuestScrollControl.extent = %width @ " " @ %height + %margin;
      BaseQuestScrollControl.vScrollBar = "dynamic";
   }
   BaseQuestScrollControl.updateScrollBars();
}

function clientCmdCreateQuest(%required, %titleText, %trigger, %description, %reward)
{
   CreateQuest(%required, %titleText, %trigger, %description, %reward);
}

// this function creates a quest, placing the quest depending on
// how many quests have already been created and in the required
// column if %required is true (the optional column otherwise).
// the description and reward are only displayed when the quest
// is selected, and a quest can only be selected if it has at
// least one task
function CreateQuest(%required, %titleText, %trigger, %description, %reward)
{
   // get the positions for the check box and quest text that
   // will be created based on if the quest is required or optional
   if (%required == true)
   {
      %checkPos = GetRequiredCheckPosition($QuestRequiredCount);
      %checkTemplate = QuestRequiredList.getChild(BeginQuestCheck);
      
      %titlePos = GetRequiredTitlePosition($QuestRequiredCount);
      %titleTemplate = QuestRequiredList.getChild(BeginQuestTitle);
   }
   else
   {
      %checkPos = GetOptionalCheckPosition($QuestOptionalCount);
      %checkTemplate = QuestOptionalList.getChild(BeginQuestCheck);
      
      %titlePos = GetOptionalTitlePosition($QuestOptionalCount);
      %titleTemplate = QuestOptionalList.getChild(BeginQuestTitle);
   }
   
   // create the check box
   %check = new SLImage()
   {
      visible = "1";
      input = "0";
      onTop = "1";
      horizSizing = "relative";
      vertSizing = "relative";
      iconOffset = %checkTemplate.iconOffset;
      iconAlpha = %checkTemplate.iconAlpha;
      iconEnabled = %checkTemplate.iconEnabled;
      iconDisabled = %checkTemplate.iconDisabled;
      stateUp = %checkTemplate.stateDisabled;
      stateDown = %checkTemplate.stateDown;
      position = %checkPos;
      extent = %checkTemplate.extent;
      profile = %checkTemplate.profile;
   };
   
   // create the quest text
   %title = new SLTextImage()
   {
      disabled = "1";
      visible = "1";
      input = "0";
      onTop = "1";
      horizSizing = "relative";
      vertSizing = "relative";
      iconOffset = %titleTemplate.iconOffset;
      iconAlpha = %titleTemplate.iconAlpha;
      iconEnabled = %titleTemplate.iconEnabled;
      iconDisabled = %titleTemplate.iconDisabled;
      textDown = %titleText;
      stateUp = %titleTemplate.stateUp;
      stateFocus = %titleTemplate.stateFocus;
      stateDown = %titleTemplate.stateDown;
      stateDisabled = %titleTemplate.stateDisabled;
      position = %titlePos;
      extent = %titleTemplate.extent;
      profile = %titleTemplate.profile;
      textIndent = %titleTemplate.textIndent;
   };
   
   // the quest is unknown until a task is added to it, so blank out
   // all of the quest words with question marks until a task is added
   %count = getWordCount(%titleText);
   %data = "";
   for (%index = 0; %index < %count; %index++)
   {
      %word = getWord(%titleText, %index);
      %charCount = strlen(%word);
      for (%charIndex = 0; %charIndex < %charCount; %charIndex++)
      {
         %data = %data @ "?";
      }
      %data = %data @ " ";
   }
   
   // save data (storage)
   %title.textUp = %data;
   %title.textDisabled = %data;
   %title.trigger = %trigger;
   %title.description = %description;
   %title.reward = %reward;
   %title.check = %check;
   
   // place the check box and quest title and update counters
   if (%required == true)
   {
      QuestRequiredList.addGuiControl(%check);
      QuestRequiredList.addGuiControl(%title);
      $QuestRequiredData[$QuestRequiredCount, 0] = %check;
      $QuestRequiredData[$QuestRequiredCount, 1] = %title;
      $QuestRequiredCount++;
   }
   else
   {
      QuestOptionalList.addGuiControl(%check);
      QuestOptionalList.addGuiControl(%title);
      $QuestOptionalData[$QuestOptionalCount, 0] = %check;
      $QuestOptionalData[$QuestOptionalCount, 1] = %title;
      $QuestOptionalCount++;
   }
}

// this function clears all of the task information for the quests
// (the description and the reward as well-- all of the info)
function ClearQuests()
{
   // clear base experience information
   QuestRequiredList.getChild(BeginQuestTitle).visible = false;
   QuestRequiredList.getChild(NextQuestTitle).visible = false;
   QuestRequiredList.getChild(BeginQuestCheck).visible = false;
   QuestRequiredList.getChild(NextQuestCheck).visible = false;
   QuestOptionalList.getChild(BeginQuestTitle).visible = false;
   QuestOptionalList.getChild(NextQuestTitle).visible = false;
   QuestOptionalList.getChild(BeginQuestCheck).visible = false;
   QuestOptionalList.getChild(NextQuestCheck).visible = false;
   QuestDescription.stateUp = "";
   QuestRewardText.stateUp = "";
   BeginQuestTaskLong.visible = false;
   NextQuestTaskLong.visible = false;
   BeginQuestTaskCheck.visible = false;
   NextQuestTaskCheck.visible = false;
   StrikeQuest.visible = false;
}

// returns the quest object given the quest title (0 is returned
// if the quest could not be found)
function GetQuestObject(%title)
{
   // check if the title is in the required list
   for (%index = 0; %index < $QuestRequiredCount; %index++)
   {
      %foundTitle = $QuestRequiredData[%index, 1];
      if (%title $= $QuestRequiredData[%index, 1].textDown)
      {
         return %foundTitle;
      }
   }
   
   // check if the title is in the optional list
   for (%index = 0; %index < $QuestOptionalCount; %index++)
   {
      %foundTitle = $QuestOptionalData[%index, 1];
      if (%title $= $QuestOptionalData[%index, 1].textDown)
      {
         return %foundTitle;
         break;
      }
   }
   
   return 0;
}

function clientCmdReadyQuest(%title)
{
   ReadyQuest(%title);
}

// this makes a quest available (only if the quest is in an unknown state)
function ReadyQuest(%title)
{
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return false;
   }
   
   if (%foundTitle.input == true)
   {
      return false;
   }
   
   if (isObject(%foundTitle.strike) == true)
   {
      return false;
   }
   
   %parent = %foundTitle.getParent();
   %check = %parent.getChild(BeginQuestCheck);
   %foundTitle.check.stateUp = %check.stateUp;
   %foundTitle.input = true;
   %foundTitle.command = "ShowTrigger(" @ %foundTitle @ ");";
   %foundTitle.textUp = %foundTitle.textDown;
   %foundTitle.textDisabled = %foundTitle.textDown;
   %foundTitle.disabled = false;
   return true;
}

function clientCmdDisableQuest(%title)
{
   DisableQuest(%title);
}

// this makes a quest disabled from a previous state (cannot disable
// an already-disabled quest)
function DisableQuest(%title)
{
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return false;
   }
   
   if (isObject(%foundTitle.strike) == true)
   {
      return false;
   }
   
   %parent = %foundTitle.getParent();
   %check = %parent.getChild(BeginQuestCheck);
   %foundTitle.check.stateUp = %check.stateDisabled;
   %foundTitle.input = false;
   %foundTitle.disabled = true;
   
   %strikeDiff = GetStrikePositionDiff();
   %xPos = getWord(%foundTitle.position, 0) + getWord(%strikeDiff, 0);
   %yPos = getWord(%foundTitle.position, 1) + getWord(%strikeDiff, 1);
   %foundTitle.strike = new SLImage()
   {
      visible = "1";
      input = "0";
      onTop = "1";
      horizSizing = "relative";
      vertSizing = "relative";
      stateUp = StrikeQuest.stateUp;
      position = %xPos @ " " @ %yPos;
      extent = StrikeQuest.extent;
      profile = StrikeQuest.profile;
   };
   %parent.addGuiControl(%foundTitle.strike);
   
   // if the quest has already been added, it cannot be performed
   // now that it is disabled, so the quest should be removed
   RemoveQuest(%foundTitle.textDown);
   
   // check if the quest information should be hidden
   if ($QuestShowInfo == %foundTitle)
   {
      HideQuest(%foundTitle);
      $QuestShowInfo = 0;
   }
   return true;
}

function clientCmdReplaceQuestTask(%title, %oldbrief, %newbrief, %newlong)
{
   ReplaceQuestTask(%title, %oldbrief, %newbrief, %newlong);
}

// this function is used to find out how many brief tasks have been
// assigned to a quest with a particular long description
function GetQuestTaskBriefCount(%title, %long)
{
   // if the quest title is not found, return 0
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return 0;
   }
   
   // if the brief field has not been set
   if (%foundTitle.tasks $= "") %foundTitle.tasks = 0;
   %taskCount = %foundTitle.tasks;
   for (%index = 0; %index < %taskCount; %index++)
   {
      // if the long description is found, then return the
      // number of brief descriptions associated with it
      %checkLong = %foundTitle.tasks[%index, 2];
      if (%long $= %checkLong)
      {
         return %foundTitle.tasks[%index, 0];
      }
   }
   
   // if the long description is not found, return 0
   return 0;
}

// this function returns the text for a brief description based on
// the title of the quest, the long description of the quest, and
// the brief index (between >= 0 and < GetQuestTaskBriefCount
function GetQuestTaskBrief(%title, %long, %briefIndex)
{
   // if the quest title is not found, return ""
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return "";
   }
   
   // if the brief field has not been set
   if (%foundTitle.tasks $= "") %foundTitle.tasks = 0;
   %taskCount = %foundTitle.tasks;
   for (%index = 0; %index < %taskCount; %index++)
   {
      // if the long description is found, then return the
      // brief description associated with the index (ONLY
      // if the index is valid)
      %checkLong = %foundTitle.tasks[%index, 2];
      if (%long $= %checkLong)
      {
         // if the index is not valid, return ""
         %briefCount = %foundTitle.tasks[%index, 0];
         if (%briefIndex < 0 || %briefIndex >= %briefCount)
         {
            return "";
         }
         
         // return the brief task
         return %foundTitle.tasks[%index, 0, %briefIndex];
      }
   }
   
   // if the long description is not found, return ""
   return "";
}

// this looks for the first brief message that has not been completed
// and replaces the long description with a new message, then does
// the same for the brief message (if the brief message could not
// be found, it will be added as if by calling CreateQuestTask,
// where %brief and %long are the new descriptions)
function ReplaceQuestTask(%title, %oldbrief, %newbrief, %newlong)
{
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return false;
   }
   
   // if the brief field has not been set
   if (%foundTitle.tasks $= "") %foundTitle.tasks = 0;
   %taskCount = %foundTitle.tasks;
   for (%index = 0; %index < %taskCount; %index++)
   {
      // iterate through the brief messages, look at those that
      // make the old brief message specified and are not complete
      %briefCount = %foundTitle.tasks[%index, 0];
      for (%briefIndex = 0; %briefIndex < %briefCount; %briefIndex++)
      {
         // check if we found a brief flag match that is not part
         // of a completed task (then replace the messages)
         %brief = %foundTitle.tasks[%index, 0, %briefIndex];
         if (%brief $= %oldbrief && %foundTitle.tasks[%index, 0] !=
            %foundTitle.tasks[%index, 1])
         {
            // replace existing gui messages
            %foundTitle.tasks[%index, 0, %briefIndex] = %newbrief;
            %foundTitle.tasks[%index, 2] = %newlong;
            
            // replace the existing hud message
            ReplaceQuestTaskBrief(%title, %oldbrief, %newbrief);
            return;
         }
      }
   }
   
   // if the task could not be found to replace, add it
   CreateQuestTask(%title, %newbrief, %newlong);
}

function clientCmdCreateQuestTask(%title, %brief, %long)
{
   CreateQuestTask(%title, %brief, %long);
}

// creates a task given the title of the quest that the task is
// associated with (the a brief description and long description
// are given to the quest-- long information is displayed in this
// page, while brief information is displayed in the quest hud)
// possible brief-long combos: ("", "long"), ("b1", "long") and
// ("b2", "long) and ..., ("brief", "long")
function CreateQuestTask(%title, %brief, %long)
{
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return false;
   }
   
   // if the brief field has not been set
   if (%foundTitle.tasks $= "") %foundTitle.tasks = 0;
   %taskCount = %foundTitle.tasks;
   for (%index = 0; %index < %taskCount; %index++)
   {
      // if the brief description is added to a long description
      // that already exists, then add the task to the list of
      // tasks to complete and reference the long description
      if (%foundTitle.tasks[%index, 2] $= %long)
      {
         %briefCount = %foundTitle.tasks[%index, 0];
         %foundTitle.tasks[%index, 0, %briefCount] = %brief;
         %foundTitle.tasks[%index, 0]++;
         %foundTitle.check.stateUp = BeginQuestCheck.stateFocus;
         
         AddQuestTask(%title, %brief);
         return true;
      }
   }
   
   %foundTitle.textUp = %foundTitle.textDown;
   %foundTitle.textDisabled = %foundTitle.textDown;
   %foundTitle.input = true;
   %foundTitle.disabled = false;
   %foundTitle.command = "ShowQuest(" @ %foundTitle @ ");";
   
   // otherwise we are adding a completely new checkbox and long task (check
   // for a long task that is not linked to a brief task)
   if (%brief $= "")
   {
      %foundTitle.tasks[%taskCount, 0] = 0;
      %foundTitle.tasks[%taskCount, 1] = 0;
      %foundTitle.tasks[%taskCount, 2] = %long;
      %foundTitle.tasks++;
      %foundTitle.check.stateUp = BeginQuestCheck.stateFocus;
      
      if (%taskCount == 0) AddQuest(%title);
      return true;
   }
   
   // otherwise, we need to add a brief-long task combination to the list of tasks   
   %foundTitle.tasks[%taskCount, 0] = 1;
   %foundTitle.tasks[%taskCount, 0, 0] = %brief;
   %foundTitle.tasks[%taskCount, 1] = 0;
   %foundTitle.tasks[%taskCount, 2] = %long;
   %foundTitle.tasks++;
   %foundTitle.check.stateUp = BeginQuestCheck.stateFocus;   
   
   if (%taskCount == 0) AddQuest(%title);
   AddQuestTask(%title, %brief);
   return true;
}

function clientCmdCompleteQuestTask(%title, %brief)
{
   CompleteQuestTask(%title, %brief);
}

// this function will check of a task that has just been completed.
// note that if there are multiple brief tasks for a long task, the
// long task is only checked off when all of the brief tasks that
// are associated with it have been completed
function CompleteQuestTask(%title, %brief)
{
   %foundTitle = GetQuestObject(%title);
   if (isObject(%foundTitle) == false)
   {
      return false;
   }
   
   // look for the matching brief description of the task
   %taskCount = %foundTitle.tasks;
   for (%index = 0; %index < %taskCount; %index++)
   {
      %checked = false;
      
      // look at the brief tasks of this task
      %briefCount = %foundTitle.tasks[%index, 0];
      for (%briefIndex = 0; %briefIndex < %briefCount; %briefIndex++)
      {
         // if the brief task is found, try to complete the task
         %checkBrief = %foundTitle.tasks[%index, 0, %briefIndex];
         if (%brief $= %checkBrief)
         {
            %checked = CheckQuestTask(%title, %brief);
            if (%checked == false)
            {
               return false;
            }
            
            // if the quest is successfully checked, update the check
            // in the quest page and see if the quest is complete
            %foundTitle.tasks[%index, 1]++;
            break;
         }
      }
      
      // if the task was found and checked, look through all of the
      // tasks for this quest to see if the quest is complete
      if (%checked == true)
      {
         for (%index = 0; %index < %taskCount; %index++)
         {
            // if we found a task that is not complete, no need to look further
            if (%foundTitle.tasks[%index, 0] != %foundTitle.tasks[%index, 1])
            {
               return true;
            }
         }
         
         // if we get this far, the quest is complete
         %foundTitle.check.selected = true;
         
         // the quest is already complete
         if (isObject(%foundTitle.complete) == false)
         {
            // set up the complete image that will be displayed
            %diff = GetCompletePositionDiff();
            %xPos = getWord(%foundTitle.position, 0) + getWord(%diff, 0);
            %yPos = getWord(%foundTitle.position, 1) + getWord(%diff, 1);
            %foundTitle.complete = new SLImage()
            {
               visible = "1";
               input = "0";
               onTop = "1";
               horizSizing = "relative";
               vertSizing = "relative";
               stateUp = CompleteQuest.stateUp;
               position = %xPos @ " " @ %yPos;
               extent = CompleteQuest.extent;
               profile = CompleteQuest.profile;
            };
            
            %parent = %foundTitle.getParent();
            %parent.addGuiControl(%foundTitle.complete);
         }
         return true;
      }
   }
   
   return false;
}

// this function hides the quest information at the bottom of the
// quest screen
function HideQuest(%title)
{
   QuestDescription.stateUp = "";
   QuestRewardText.stateUp = "";
   
   for (%index = 0; %index < %title.tasks; %index++)
   {
      %object = nameToId("QuestLong" @ %index);
      if (isObject(%object) == true)
      {
         %object.delete();
      }
      
      %object = nameToId("QuestCheck" @ %index);
      if (isObject(%object) == true)
      {
         %object.delete();
      }
   }
   
   UpdateQuestControlScrollExtent(0);
   %title.selected = false;
}

// this function is used to show the trigger information for an
// available (but not active) quest
function ShowTrigger(%title)
{
   if ($QuestShowInfo != 0)
   {
      HideQuest($QuestShowInfo);
   }
   
   $QuestShowInfo = %title;
   QuestDescription.stateUp = %title.trigger;
   %title.selected = true;
}

// this function shows the quest information at the bottom of the
// quest screen
function ShowQuest(%title)
{
   if ($QuestShowInfo != 0)
   {
      HideQuest($QuestShowInfo);
   }
   
   $QuestShowInfo = %title;
   QuestDescription.stateUp = %title.description;
   QuestRewardText.stateUp = %title.reward;
   
   for (%index = 0; %index < %title.tasks; %index++)
   {
      %longPos = GetLongTextPosition(%index);
      %long = new SLText("QuestLong" @ %index)
      {
         visible = "1";
         input = "0";
         onTop = "1";
         horizSizing = "relative";
         vertSizing = "relative";
         stateUp = %title.tasks[%index, 2];
         position = %longPos;
         extent = BeginQuestTaskLong.extent;
         profile = BeginQuestTaskLong.profile;
      };
      
      %checkPos = GetLongCheckPosition(%index);
      %check = new SLImage("QuestCheck" @ %index)
      {
         visible = "1";
         input = "0";
         onTop = "1";
         horizSizing = "relative";
         vertSizing = "relative";
         stateUp = BeginQuestTaskCheck.stateUp;
         stateDown = BeginQuestTaskCheck.stateDown;
         position = %checkPos;
         extent = BeginQuestTaskCheck.extent;
         profile = BeginQuestTaskCheck.profile;
      };
      %check.selected = (%title.tasks[%index, 0] == %title.tasks[%index, 1]);
      
      QuestScrollControl.addGuiControl(%long);
      QuestScrollControl.addGuiControl(%check);
   }
   
   UpdateQuestControlScrollExtent(%title.tasks);
   %title.selected = true;
}

function QuestResolutionChange(%width, %height)
{
   // 800 x 600 resolution
   %offset = getWords($QuestIconPos_800x600, 0, 1);
   if (%width == 800)
   {
      %offset = getWords($QuestIconPos_800x600, 0, 1);
   }
   // 1024 x 768 resolution
   else if (%width == 1024)   
   {
      %offset = getWords($QuestIconPos_1024x768, 0, 1);
   }
   // 1280 x 768 resolution
   else if (%height == 768)
   {
      %offset = getWords($QuestIconPos_1280x768, 0, 1);
   }
   // 1280 x 800 resolution
   else
   {
      %offset = getWords($QuestIconPos_1280x800, 0, 1);
   }
   
   // update the required list
   %title = QuestRequiredList.getChild(BeginQuestTitle);
   %title.iconOffset = %offset;
   
   // update the optional list
   %title = QuestOptionalList.getChild(BeginQuestTitle);
   %title.iconOffset = %offset;
   
   // required button list
   for (%index = 0; %index < $QuestRequiredCount; %index++)
   {
      %title = $QuestRequiredData[%index, 1];
      %title.iconOffset = %offset;
   }
   
   // optional button list
   for (%index = 0; %index < $QuestOptionalCount; %index++)
   {
      %title = $QuestOptionalData[%index, 1];
      %title.iconOffset = %offset;
   }
}
