/* Resources are used to complete Tasks.  Resources have
   associated costs.  Examples of Resources would be a 
   person or a machine.  Resources are kept in a collection.

   When assigning resources their availability and usage
   should be tracked.  This is not yet implemented.
*/!!

inherit(Object, #Resource, #(
name          /* description   */
fixedCost     /* per usage     */
variableCost  /* per time used */
references    /* set of Tasks  */
maximum       /* Not yet used  */
usage         /* Not yet used  */), 2, nil)!!

now(ResourceClass)!!

/* Create a new Resource. */
Def  new(self)
{ 
  ^init(new(self:Behavior));
}!!

now(Resource)!!

/* Delete a resource.  First check to see if it is
   used anywhere and check with the user. */
Def  delete(self, project)
{ 
  if size(references) = 0
    cor yesNoBox(loadString(PW_WARNING),
                 loadString(PW_RESOURCE) + " " + name +
                 loadString(PW_RESUSE) + CR_LF +
                 loadString(PW_DELETE)) == IDYES
     do(references,
       {using(aTask) 
        removeResource(aTask, self);
     });
    remove(project.resources, self.name);    
  endif;      
}!!

/* Return a string of all activities that reference a resource. */
Def  getRefsString(self | str)
{ 
  str := "";
  do(references,
    {using(ref) 
     str := str + getName(ref) + " ";
  });

  if size(str) > 20 then
    str := subString(str, 0, 18) + "..";
  endif;
  ^str;
}!!

/* Return a string to be used as a caption in a window. */
Def  makeCaption(self)
{
  ^loadString(PW_RESOURCE) + ": "+getName(self);
}!!

/* Get the amount used of a resource. */
Def  getUsed(self | used)
{ 
  used := 0;
  do(references,
    {using(aTask)
     used := used + getTime(aTask);
   });
  ^used;
}!!

/* Summarize useful information on a single line. */
Def  getInfoLine(self | used, str)
{
  used := getUsed(self);
  if maximum cand used > maximum
     str := "*";
  else
     str := " ";
  endif;
  ^str 
   + field(name, 6) 
   + field(asString(getMaximum(self)), 3) + " " 
   + field(asString(used), 3) + " "
   + field(asString(getFixedCost(self)), 3) + " " 
   + field(asString(getVariableCost(self)), 3) + " "
   + field(getRefsString(self),20);
}!!

/* Set the values of a resource. 
   Values is an array of name, maximum,
   fixedCost, variableCost. */
Def  setValues(self, values)
{
  name := values[0];
  maximum := values[1];
  setFixedCost(self, values[2]);
  setVariableCost(self, values[3]);
}!!

/* Display and edit the resource information. 
   The dialog should define methods run() and setEditItem().
*/
Def  editInfo(self | dlg, retValue)
{
  showWaitCurs();
  dlg := new(ResDialog); 
  setEditItem(dlg, self);
  retValue := run(dlg, ThePort);
  showOldCurs();
  ^retValue;
}!!

/* Print a resource. */
Def  printOn(self, aStream)
{ 
  printOn(name, aStream);
}!!

/* Set the name of a resource. */
Def  setName(self, aName)
{ name := aName;
}!!

/* Set the variableCost of a resource.  If necessary,
   update the cost of any Tasks that reference it. */
Def  setVariableCost(self, aCost | oldCost)
{ 
  if (aCost <> variableCost)
    oldCost := variableCost;
    variableCost := aCost;
    do(references,
      {using(aTask) updateCost(aTask, variableCost - oldCost);
    });
  endif;
}!!

/* Get the variableCost of a resource. */
Def  getVariableCost(self)
{ ^variableCost;
}!!

/* Set the fixedCost of a resource.  If necessary,
   update the cost of any Tasks that reference it. */
Def  setFixedCost(self, aCost | oldCost)
{ 
  if (aCost <> fixedCost)
    oldCost := fixedCost;
    fixedCost := aCost;
    do(references,
      {using(aTask) updateCost(aTask, fixedCost - oldCost);
    });
  endif;
}!!

/* Get the fixedCost of a resource. */
Def  getFixedCost(self)
{ ^fixedCost;
}!!

/* Remove a reference to a resource. */
Def  removeReference(self, aTask)
{ remove(references, aTask);
}!!

/* Add a reference to a resource. */
Def  addReference(self, aTask)
{ add(references, aTask);
}!!

/* Get the maximum available of a resource. */
Def  getMaximum(self)
{ if maximum
    ^maximum;
  else
    ^"";
  endif;
}!!

/* Get the name of a resource. */
Def  getName(self)
{ ^name;
}!!

/* Initialize a new resource. */
Def  init(self)
{
  name := "";
  maximum := nil;              /* unlimited */
  variableCost := 0;
  fixedCost := 0;
  references := new(Set, 10);  /* where used */
}!!

