/* ==========================================================================
**
**                          GraphicObject.c
**
**   ©1991 WILLISoft
**
** ==========================================================================
*/
#include "GraphicObject.h"
#include "GraphicObjectClass.h"

void
GraphicObject_CleanUp( GraphicObject *self )
{
   SetTitle( self, NULL );
}


BOOL GraphicObject_elaborated = FALSE;

struct GraphicObjectClass GraphicObject_Class;

void GraphicObjectClass_Init( struct GraphicObjectClass *class )
{
   PObjectClass_Init( (struct PObjectClass *) class );
   class->isa            = PObjectClass();
   class->ClassName      = "GraphicObject";
   class->CleanUp        = GraphicObject_CleanUp;
   class->Location       = NULL;
   class->SetLocation    = NULL;
   class->Size           = NULL;
   class->AskSize        = NULL;
   class->SetSize        = NULL;
   class->SizeFlags      = GraphicObject_SizeFlagsAll;
                           /* default to sizeable on both axis. */
   class->Render           = NULL;
   class->SetTitle         = NULL;
   class->Title            = NULL;
   class->BuilderMethods   = NULL;
   class->TextAlignment    = NULL;
   class->SetTextAlignment = NULL;
}


struct GraphicObjectClass *GraphicObjectClass( void )
{
   if (! GraphicObject_elaborated)
   {
      GraphicObjectClass_Init( &GraphicObject_Class );
      GraphicObject_elaborated = TRUE;
   }

   return &GraphicObject_Class;
}



Point Point_ZeroZero = {0,0};


Point Location( GraphicObject *self )
/* Returns the LeftEdge, TopEdge of 'self'. */
{
   Point                     pos;
   struct GraphicObjectClass *class;

   pos = Point_ZeroZero;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->Location)
         pos = (*class->Location)( self );
   }
   return pos;
}


Point SetLocation( GraphicObject *self,
                   PIXELS         LeftEdge,
                   PIXELS         TopEdge )
/* Sets the LeftEdge, TopEdge of 'self'.
 * Returns the LeftEdge, TopEdge.
 */
{
   Point                     pos;
   struct GraphicObjectClass *class;

   pos = Point_ZeroZero;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->SetLocation)
         pos = (*class->SetLocation)( self, LeftEdge, TopEdge );
   }
   return pos;
}


Point Size( GraphicObject *self )
/* Returns the Width, Height of 'self'.
 */
{
   Point                      size;
   struct GraphicObjectClass *class;

   size = Point_ZeroZero;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->Size)
         size = (*class->Size)( self );
   }
   return size;
}


Point AskSize( GraphicObject *self,
               PIXELS         Width,
               PIXELS         Height )
/* Given a (Width, Height), returns the nearest (Width, Height)
 * that 'self' modify itself to be.  Does NOT actually change
 * the dimensions of 'self'.
 */
{
   Point                       size;
   struct GraphicObjectClass *class;

   size = Point_ZeroZero;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->AskSize)
         size = (*class->AskSize)( self, Width, Height );
   }
   return size;
}


Point SetSize( GraphicObject *self,
                PIXELS         Width,
                PIXELS         Height )
/* Sets 'self's size to be as near (Width, Height) as possible,
 * returns the actual (Width, Height).
 */
{
   Point                       size;
   struct GraphicObjectClass *class;

   size = Point_ZeroZero;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->SetSize)
         size = (*class->SetSize)( self, Width, Height );
   }
   return size;
}


UWORD SizeFlags( GraphicObject *self )
{
   struct GraphicObjectClass *class;
   UWORD flags;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->SizeFlags)
         flags = (*class->SizeFlags)( self );
   }
   return flags;
}



void Render( GraphicObject *self,
             RastPort      *RPort )
{
   struct GraphicObjectClass *class;


   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->Render)
         (*class->Render)( self, RPort );
   }
}



UWORD GraphicObject_SizeFlagsNone( GraphicObject *self )
{
   return 0;
}

UWORD GraphicObject_SizeFlagsX( GraphicObject *self )
{
   return OBJSIZE_X;
}

UWORD GraphicObject_SizeFlagsY( GraphicObject *self )
{
   return OBJSIZE_Y;
}

UWORD GraphicObject_SizeFlagsAll( GraphicObject *self )
{
   return OBJSIZE_X | OBJSIZE_Y;
}


BOOL SetTitle( GraphicObject *self, char *title )
{
   struct GraphicObjectClass *class;


   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->SetTitle)
         return (*class->SetTitle)( self, title );
      else
         return FALSE;
   }
   return FALSE;

}


char *Title( GraphicObject *self )
/* Returns a pointer to the title of an object, or NULL if none. */
{
   struct GraphicObjectClass *class;


   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->Title)
         return (*class->Title)( self );
      else
         return NULL;
   }
   return NULL;
}

AlignInfo go_DefaultAlignment = { 0xFF, 0, 0, };

AlignInfo TextAlignment( GraphicObject *self )
{
   struct GraphicObjectClass *class;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->TextAlignment)
         return (*class->TextAlignment)(self);
      else
         return go_DefaultAlignment;
   }
}

AlignInfo SetTextAlignment( GraphicObject *self,
                            UBYTE         Flags,
                            BYTE          Xpad,
                            BYTE          Ypad )
{
   struct GraphicObjectClass *class;

   if (class = (struct GraphicObjectClass *) self->isa)
   {
      if (class->SetTextAlignment)
         return (*class->SetTextAlignment)(self, Flags, Xpad, Ypad);
      else
         return go_DefaultAlignment;
   }
}



void GraphicObject_Init( GraphicObject *self )
{
   PObject_Init( self );

   self->isa = GraphicObjectClass();
   self->Next = NULL;
}
