/* Formal class for defining attributes common to all chart types */!!

inherit(Object, #VidChart,
#(data, /* collection of data points */
labels, /* collection of strings to label data */
area,   /* area in which to draw charts */
scale,  /* point indicating scale to use */
lead,   /* lead space from edge of window */
space   /* space between bars in a chart */), 2, nil)!!

now(class(VidChart))!!

/* Class method to automatically initialize charts. */
Def new(self)
{ ^init(new(self:ancestor));
}!!

now(VidChart)!!

/* Adjusts the chart size based on data and area. */
Def reScale(self | max)
{ /* Find the largest data point. */
  max := 0;
  do(data,
  {using(item)
    if item > max
    then max := item;
    endif;
  });

  /* Adjust the size according to the largest data point. */
  if max > 0
  then resetLead(self);
    adjustScale(self, asReal(max));
    resetSpace(self);
  endif;
}!!

/* Draws the string str in the context at location 
  x, y */
Def drawText(self, x, y, str, context)
{ Call TextOut(context, x, y, str, size(str));
}!!

/* Draws a chart in the given display context. */
Def draw(self, context)
{ if area
  then drawData(self, context);
    drawLabels(self, context);
  endif;
}!!

/* Sets the area of a chart to the given point. 
  This must be done before drawing. */
Def setArea(self, aPoint)
{ area := aPoint;
}!!

/* Sets the labels of a chart to the given 
  collection. */
Def setLabels(self, aCollection)
{ labels := aCollection;
}!!

/* Sets the data of a chart to the given 
  collection. */
Def setData(self, aCollection)
{ data := aCollection;
}!!

/* Sets the space instance variable. Descendant 
  classes can override this method. */
Def resetSpace(self)
{ space := 10;
}!!

/* Set the lead instance variable to a point.
   Descendant classes can override this method. */
Def resetLead(self)
{ lead := point(10,10);
}!!

/* Sets the scale instance variable to a point.
   Descendant classes can override this method. */
Def resetScale(self)
{ scale := point(10, 10);
}!!

/* Initializes new chart objects */
Def init(self)
{ data := new(OrderedCollection, 10);
  labels := new(OrderedCollection, 10);
  resetScale(self);
  resetLead(self);
  resetSpace(self);
}!!
