#include <stdio.h>
#include "CheckBox.h"
#include "CheckBoxClass.h"
#include "Precognition_utils.h"
#include "minmax.h"
#include "AmigaMem.h"
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/exec.h>

typedef struct CheckInfo
   {
      Border CheckMark;
      BOOL   Selected;
   } CheckInfo;



WORD CheckBox_CheckMarkPoints[] = { 16,3, 9,10, 6,10, 6,6, 7,6, 7,10,
         14,3, 15,3, 8,10, 8,5, 4,5 };




void CheckBox_CleanUp( CheckBox *self )
{
   Afree( self->g.SpecialInfo );
   self->g.SpecialInfo = NULL;
}


tPoint CheckBox_FixedSize = { 22, 14 };

tPoint CheckBox_AskSize( CheckBox *self,
                         PIXELS    Width,
                         PIXELS    Height )
{
   return CheckBox_FixedSize;
}



USHORT CheckBox_ClaimEvent( CheckBox   *self,
                            IntuiMessage  *event )
{
   USHORT response = 0;

   switch (event->Class)
   {
      case REFRESHWINDOW:
         response = RESPONDED;
         break;

      case GADGETUP:
         if (event->IAddress == (void*) &self->g)
         {
            response = RESPONDED | CONSUMED_EVENT | CHANGED_STATE;
         }
         break;
   }

   return response;
}


LONG CheckBox_Value( CheckBox *self )
{
   CheckInfo *info;

   info = (CheckInfo *) self->g.SpecialInfo;

   return (LONG) info->Selected;
}


LONG CheckBox_SetValue( CheckBox *self,
                            LONG      selection )
{
   CheckInfo *info;

   info = (CheckInfo *) self->g.SpecialInfo;

   info->Selected = selection;

   if (selection)
   {
      Forbid();
      self->BoxBorder->BottomRight.NextBorder = &info->CheckMark;
      Permit();
   }
   else
   {
      Forbid();
      self->BoxBorder->BottomRight.NextBorder = NULL;
      Permit();
   }

   return (LONG) info->Selected;
}

void CheckBox_Render( CheckBox *self,
                      RastPort *RPort )
{
   PIXELS xmin, xmax, ymin, ymax;

   xmin = self->Location.x + 2;
   ymin = self->Location.y + 2;
   xmax = xmin + self->Size.x - 4;
   ymax = ymin + self->Size.y - 4;
   SetAPen( RPort, self->Pens.BackPen );
   SetDrMd( RPort, JAM1 );
   RectFill( RPort, xmin, ymin, xmax, ymax );

   EmbossedGadget_Render( self, RPort );
}


USHORT CheckBox_Respond( CheckBox     *self,
                         IntuiMessage *event )
{
   CheckInfo *info;
   USHORT     response = 0;
   Window    *window;
   USHORT     selection;

   switch (event->Class)
   {
      case REFRESHWINDOW:
         response = RESPONDED;
         break;

      case GADGETUP:
         if (event->IAddress == (void*) &self->g)
         {
            window = event->IDCMPWindow;

            info      = (CheckInfo *) self->g.SpecialInfo;
            selection = ! info->Selected;

            SetValue( self, selection );
            Render( self, window->RPort );

            response = RESPONDED | CONSUMED_EVENT | CHANGED_STATE;
         }
         break;

   }

   return response;


}

#ifdef BUILDER
#include "BuilderMethods.h"
#include "GraphicObject_Builder.h"
#include "CheckBox_Builder.h"
#include "Checkbox_coder.h"

struct BuilderMethods CheckBox_bm;
#endif

BOOL CheckBox_elaborated = FALSE;

struct ValuatorClass CheckBox_Class;

void CheckBoxClass_Init( struct ValuatorClass *class )
{
   BoolGadgetClass_Init( class );
   class->isa         = BoolGadgetClass();
   class->ClassName   = "CheckBox";

/* -------- Commented-out methods are inherited ----------------*/
   class->CleanUp     = CheckBox_CleanUp;
/*   class->Location    = CheckBox_Location;*/
/*   class->SetLocation = CheckBox_SetLocation;*/
/*   class->Size        = CheckBox_Size;*/
/*   class->SetSize     = CheckBox_SetSize;*/
   class->AskSize     = CheckBox_AskSize;
   class->SizeFlags  = GraphicObject_SizeFlagsNone;
   class->Render      = CheckBox_Render;
/*   class->FirstGadget = CheckBox_FirstGadget;*/
/*   class->nGadgets    = CheckBox_nGadgets;*/
/*   class->IDCMPFlags  = CheckBox_IDCMPFlags;*/
   class->ClaimEvent  = CheckBox_ClaimEvent;
   class->Respond     = CheckBox_Respond;
/*   class->EnableIactor      = CheckBox_EnableIactor;*/
/*   class->isEnabled   = CheckBox_isEnabled;*/
/*   class->Activate    = NULL;*/
/*   class->isActive    = NULL;*/
   class->Value     = CheckBox_Value;
   class->SetValue  = CheckBox_SetValue;

#ifdef BUILDER
   class->BuilderMethods = &CheckBox_bm;
   go_InitBuilderMethods( &CheckBox_bm );
   CheckBox_bm.New       = CheckBox_New;
   CheckBox_bm.PropEdit  = CheckBox_PropEdit;
   CheckBox_bm.WriteCode = CheckBox_WriteCode;
#endif

}


struct ValuatorClass *CheckBoxClass( void )
{
   if (! CheckBox_elaborated)
   {
      CheckBoxClass_Init( &CheckBox_Class );
      CheckBox_elaborated = TRUE;
   }

   return &CheckBox_Class;
}


void CheckBox_Init( CheckBox *self,
                    PIXELS      LeftEdge,
                    PIXELS      TopEdge,
                    pcg_3DPens  Pens,
                    char       *Label,
                    BOOL        Selected )
{
   tPoint     size;
   CheckInfo *info;
   AlignInfo  ainfo;

/*DUMPWAIT("CheckBox_Init\n");*/

   Interactor_Init(self);

   self->isa  = CheckBoxClass();
   size       = AskSize( self, 0, 0 );


   BoolGadget_Init( self, LeftEdge, TopEdge, size.x, size.y,
                        Pens, Label );
   
   self->isa     = CheckBoxClass();
   self->g.Flags = GADGHCOMP;

   ainfo = TextAlignment( self );
   SetTextAlignment( self, tx_RIGHT | tx_YCENTER | tx_OUTSIDE,
      ainfo.Xpad, ainfo.Ypad );

   info = (CheckInfo *) Acalloc( 1, sizeof(CheckInfo) );
   info->Selected         = Selected;

   info->CheckMark.LeftEdge   = 0;
   info->CheckMark.TopEdge    = 0;
   info->CheckMark.FrontPen   = Pens.FrontPen;
   info->CheckMark.BackPen    = Pens.BackPen;
   info->CheckMark.DrawMode   = JAM1;
   info->CheckMark.Count      = 11;
   info->CheckMark.XY         = CheckBox_CheckMarkPoints;
   info->CheckMark.NextBorder = NULL;
   self->g.SpecialInfo        = (APTR) info;

   SetValue( self, (USHORT) Selected );

/*DUMPWAIT("end Checkbox_Init\n");*/
}
