
#include "OutlineBox.h"
#include "GraphicObjectClass.h"
#include <stdlib.h>
#include <string.h>
#include "minmax.h"
#include <graphics/gfxmacros.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include "amigamem.h"


tPoint OutlineBox_Location( OutlineBox *self )
{
   return self->Location;
}


tPoint OutlineBox_SetLocation( OutlineBox *self,
                             PIXELS    LeftEdge,
                             PIXELS    TopEdge )
{
   self->Location.x = LeftEdge;
   self->Location.y = TopEdge;
   return self->Location;
}

tPoint OutlineBox_Size( OutlineBox *self )
{
   return self->Size;
}

tPoint OutlineBox_AskSize( OutlineBox      *self,
                         PIXELS         Width,
                         PIXELS         Height )
{
   tPoint size;

   size.x = MAX( Width, 6 );
   size.y = MAX( Height, 6 );
   return size;
}


tPoint OutlineBox_SetSize( OutlineBox *self,
                         PIXELS    Width,
                         PIXELS    Height )
{
   tPoint size;

   size = AskSize( self, Width, Height );
   self->Size.x = size.x;
   self->Size.y = size.y;

   pcg_Init3DThinBevel( &self->Bevel, 0,0, size.x, size.y, 0,
      self->Pens.DarkPen, self->Pens.BrightPen, NULL );

   return size;
}


#define FONT_WIDTH  8
#define FONT_HEIGHT 8
#define BASELINE    7

void OutlineBox_Render( OutlineBox *self,
                      RastPort *RPort )
{
   short width, length, x, y;
   Point location;
   Point size;

   location = Location(self);
   size     = Size(self);
   length   = strlen(self->Label);
   width    = length * FONT_WIDTH;
   x        = location.x + size.x/2 - width/2;
   y        = location.y - FONT_HEIGHT/2 + BASELINE;

   DrawBorder( RPort, (struct Border*) &self->Bevel, location.x, location.y );

   SetDrMd( RPort, JAM2 );
   SetAPen( RPort, self->Pens.FrontPen );
   SetBPen( RPort, self->Pens.BackPen );
   Move( RPort, x, y );
   Text( RPort, self->Label, length );
}

char *OutlineBox_Title( OutlineBox *self )
{
   return self->Label;
}

BOOL OutlineBox_SetTitle( OutlineBox *self, char *title )
{
   Afree( self->Label );
   self->Label = Astrdup(title);
   return TRUE;
}


#ifdef BUILDER
#include "BuilderMethods.h"
#include "GraphicObject_Builder.h"
#include "OutlineBox_coder.h"

OutlineBox *OutlineBox_New( OutlineBox *self )
{
   OutlineBox *new_box = NULL;

   if (new_box = Amalloc(sizeof(OutlineBox)))
   {

      OutlineBox_Init( new_box, self->Location.x, self->Location.y,
         self->Size.x, self->Size.y, self->Pens, Title(self) );

      GiveItAName(new_box);

   }

   return new_box;
}

#define YSHIFT 5

BOOL OutlineBox_InitImageBob( OutlineBox  *self,
                              ImageBob    *ibob )
{
   Point     size, location;
   UWORD     width, length, x, y;

   size     = Size(self);
   y        = size.y + YSHIFT;
   location = Location(self);

   /* Allocate memory for image. */
   if (ImageBob_Init( ibob, size.x, y, 2 ))
   {

      SetLocation( self, 0, 5 );

      Render( self, ibob->ImagePort.rastport );

      /* Draw shadow mask */
      SetDrMd ( ibob->ShadowPort.rastport, JAM2 );
      SetAPen ( ibob->ShadowPort.rastport, 1 );
      SetBPen ( ibob->ShadowPort.rastport, 1 );

      Move ( ibob->ShadowPort.rastport, 0, YSHIFT );
      Draw ( ibob->ShadowPort.rastport, size.x-1, YSHIFT );
      Draw ( ibob->ShadowPort.rastport, size.x-1, y-1 );
      Draw ( ibob->ShadowPort.rastport, 0, y-1 );
      Draw ( ibob->ShadowPort.rastport, 0, YSHIFT-1 );

      Move ( ibob->ShadowPort.rastport, 1, YSHIFT+1 );
      Draw ( ibob->ShadowPort.rastport, size.x-2, YSHIFT+1 );
      Draw ( ibob->ShadowPort.rastport, size.x-2, y-2 );
      Draw ( ibob->ShadowPort.rastport, 1, y-2 );
      Draw ( ibob->ShadowPort.rastport, 1, YSHIFT+1 );

      length   = strlen(self->Label);
      width    = length * FONT_WIDTH;
      x        = size.x/2 - width/2;
      y        = YSHIFT - FONT_HEIGHT/2 + BASELINE;

      Move( ibob->ShadowPort.rastport, x, y );
      Text( ibob->ShadowPort.rastport, self->Label, length );

      SetLocation( self, location.x, location.y ); /* restore location. */
      return TRUE;
   }
   return FALSE;
}

struct BuilderMethods OutlineBox_bm;
#endif

BOOL OutlineBox_elaborated = FALSE;

struct GraphicObjectClass OutlineBox_Class;


void OutlineBoxClass_Init( struct GraphicObjectClass *class )
{
   GraphicObjectClass_Init( class );
   class->isa         = GraphicObjectClass();
   class->ClassName   = "OutlineBox";
   class->CleanUp     = NULL;
   class->Location    = OutlineBox_Location;
   class->SetLocation = OutlineBox_SetLocation;
   class->Size        = OutlineBox_Size;
   class->AskSize     = OutlineBox_AskSize;
   class->SetSize     = OutlineBox_SetSize;
   class->SizeFlags   = GraphicObject_SizeFlagsAll;
   class->Render      = OutlineBox_Render;
   class->SetTitle    = OutlineBox_SetTitle;
   class->Title       = OutlineBox_Title;

#ifdef BUILDER
   go_InitBuilderMethods( &OutlineBox_bm );
   OutlineBox_bm.New          = OutlineBox_New;
   OutlineBox_bm.InitImageBob = OutlineBox_InitImageBob;
   OutlineBox_bm.WriteCode    = OutlineBox_WriteCode;
   class->BuilderMethods      = &OutlineBox_bm;
#endif

}


struct GraphicObjectClass *OutlineBoxClass( void )
{
   if (! OutlineBox_elaborated)
   {
      OutlineBoxClass_Init( &OutlineBox_Class );
      OutlineBox_elaborated = TRUE;
   }

   return &OutlineBox_Class;
}

void OutlineBox_Init(  OutlineBox    *self,
                       PIXELS       LeftEdge,
                       PIXELS       TopEdge,
                       PIXELS       Width,
                       PIXELS       Height,
                       pcg_3DPens   Pens,
                       char        *Label )
{
   GraphicObject_Init(self);
   
   self->isa         = OutlineBoxClass();
   self->PObjectName  = NULL;
   self->Label       = NULL;
   self->Pens        = Pens;
   SetLocation( self, LeftEdge, TopEdge );
   SetSize( self, Width, Height );
   SetTitle( self, Label );
}
