/* PERT Tasks are like regular tasks, but their time is
   calculated based on the likely, best and worst cases.

   PERTTasks descend from Task and inherit all of
   their methods and instance variables.
*/!!

inherit(Task, #PERTTask, #(likelyTime  /* for PERT calc time */ 
bestTime    /* for PERT calc time */ 
worstTime   /* for PERT calc time */
variance    /* of calculated time */), 2, nil)!!

now(PERTTaskClass)!!

now(PERTTask)!!

/* Return the class name.  Uses resources for translation. */
Def className(self)
{
  ^loadString(PW_PERTTASK);
}!!

/* Return the appropriate dialog class to be used
   by editInfo(). */
Def  dialogClass(self)
{
  ^PERTDialog;
}!!

/* Get the PERT worst time. */
Def  getWorstTime(self)
{ 
  ^worstTime;
}!!

/* Get the PERT best time. */
Def  getBestTime(self)
{ 
  ^bestTime;
}!!

/* Get the PERT likely time. */
Def  getLikelyTime(self)
{ 
  ^likelyTime;
}!!

/* Set the values of an activity. 
   Values is an array of name, desc,
   userEarlyStart, userLateFinish, likelyTime
   bestTime, worstTime, fixedCost, resources. */
Def  setValues(self, values | oldUES, oldULF, oldTime, 
                              oldLikely, oldBest, oldWorst)
{
  oldUES := userEarlyStart;
  oldULF := userLateFinish;
  oldTime := time;
  oldLikely := likelyTime;
  oldBest := bestTime;
  oldWorst := worstTime;
  
  name := values[0];
  desc := values[1];
  userEarlyStart := values[2];
  userLateFinish := values[3];
  likelyTime := values[4];
  bestTime := values[5];
  worstTime := values[6];
  
  setFixedCost(self, values[7]);
  checkResources(self, values[8]);

  if oldLikely <> likelyTime cor
      oldBest <> bestTime cor
      oldWorst <> worstTime
     calcPERT(self);    /* recalc the PERT time */
  endif;
  
  if network cand autoCalc(network) cand 
     (oldUES <> userEarlyStart cor
      oldULF <> userLateFinish cor
      oldTime <> time)
     recalc(self);     /* recalc the network */
  endif;
}!!

/* Get the PERT time, calculate it if invalidated. */
Def  getTime(self)
{ 
  if (time) 
    ^time 
  else 
    ^calcPERT(self); 
  endif;
}!!

/* Init a new PERT Task. */
Def  init(self)
{
  init(self:Task);      /* use ancestor init */
  time := 0;            /* invalidate time */
  bestTime := 0;
  worstTime := 0;
  likelyTime := 0;
  variance := 0;
} !!

/* For a PERT task, calculate the time and variance. 
   Round it to an Int. */
Def  calcPERT(self)
{ 
  variance := ((worstTime - bestTime)/6.0)**2;
  ^time := asInt(((bestTime + 4*likelyTime + worstTime) / 6.0) +.5);
}!!

