#include <stdio.h>
#include "minmax.h"
#include "Slider.h"
#include "SliderClass.h"
#include "EmbossedGadgetClass.h"
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include "amigamem.h"


/* Slider 'state' setings. */
#define WAITING    0
#define DRAGGING   1



#ifdef BUILDER

Slider *Slider_New( Slider *self )
{
   Slider *new_slider = NULL;

   if (new_slider = (Slider *) Amalloc(sizeof(Slider)))
   {
      Slider_Init( new_slider,   self->eg.Location.x, self->eg.Location.y,
                   self->eg.Size.x, self->eg.Size.y,
                   self->eg.Pens );
   }
   return new_slider;
}

#endif

void Slider_CleanUp( Slider *self )
{
   self->eg.g.SpecialInfo = NULL;

   Afree(self->eg.BoxBorder);
   self->eg.BoxBorder = NULL; 
}



void Slider_Render( Slider *self, RastPort *RPort )
{
   DrawBorder( RPort, &self->eg.BoxBorder->TopLeft,
      self->eg.Location.x, self->eg.Location.y );
}


void Slider_Refresh( Slider *self )
{
   struct pcgWindow *window;

   window = InteractorWindow( self );

   Render( self, window->Window->RPort );
   EmbossedGadget_Refresh( self );
}



#define X_BORDER_WIDTH 2
#define Y_BORDER_WIDTH 1

tPoint Slider_SetLocation(  Slider *self,
                            PIXELS  LeftEdge,
                            PIXELS  TopEdge )
{
   Forbid(); /* Don't want Intuition looking at these while we modify em. */
   self->eg.g.LeftEdge  = LeftEdge + X_BORDER_WIDTH * 2;
   self->eg.g.TopEdge   = TopEdge  + Y_BORDER_WIDTH * 2;

   self->eg.Location.x  = LeftEdge;
   self->eg.Location.y  = TopEdge;

   Permit();

   return self->eg.Location;
}



tPoint Slider_AskSize( Slider *self,
                       PIXELS  Width,
                       PIXELS  Height )
{
   tPoint size;

   size.x = MAX( Width,  10 );
   size.y = MAX( Height, 10 );

   return size;
}

tPoint Slider_SetSize( Slider *self,
                       PIXELS  Width,
                       PIXELS  Height )
{
   tPoint size;

   size = AskSize( self, Width, Height );


   Forbid(); /* Don't want Intuition looking at these while we modify em. */
   self->eg.Size     = size;
   self->eg.g.Width  = size.x - X_BORDER_WIDTH * 4;
   self->eg.g.Height = size.y - Y_BORDER_WIDTH * 4;

   pcg_Init3DBox(  self->eg.BoxBorder, 0, 0, size.x, size.y,
                   self->eg.Pens.BrightPen,  self->eg.Pens.DarkPen,
                   self->eg.BoxBorder->BottomRight.NextBorder );

   AlignText( &self->eg.LabelText, Size(self) );

   Permit();
   return size;
}




BOOL Slider_elaborated = FALSE;

struct PositionerClass Slider_Class;

void SliderClass_Init( struct PositionerClass *class )
{
   PositionerClass_Init( class );
   EmbossedGadgetClass_Init( class );
   class->isa         = PositionerClass();
   class->ClassName   = "Slider";
   class->CleanUp     = Slider_CleanUp;
   class->SetLocation = Slider_SetLocation;
   class->SetSize     = Slider_SetSize;
   class->AskSize     = Slider_AskSize;
   class->Render      = Slider_Render;
   class->Refresh     = Slider_Refresh;
   class->Activate    = NULL;
   class->isActive    = NULL;
}


struct PositionerClass *SliderClass( void )
{
   if (! Slider_elaborated)
   {
      SliderClass_Init( &Slider_Class );
      Slider_elaborated = TRUE;
   }

   return &Slider_Class;
}


#define V36_PROPNEWLOOK 0x0010
   /*
   ** This flag turns on the 3D look of the autoknob under Workbench 2.0
   ** It's ignored under 1.3
   **
   ** I've redefined it here so that I can compile under 1.3 too.
   */

void Slider_Init( Slider    *self,
                  PIXELS     LeftEdge,
                  PIXELS     TopEdge,
                  PIXELS     Width,
                  PIXELS     Height,
                  pcg_3DPens Pens )
{
   Point size;


   EmbossedGadget_Init( self, LeftEdge, TopEdge, Width, Height,
      GADGHCOMP, GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE, PROPGADGET, Pens, NULL );

   size = Slider_AskSize( self, Width, Height );

   self->eg.isa = SliderClass();
   self->eg.Size = size;

   self->eg.g.LeftEdge         = LeftEdge + X_BORDER_WIDTH*2;
   self->eg.g.TopEdge          = TopEdge  + Y_BORDER_WIDTH*2;
   self->eg.g.Width            = Width    - X_BORDER_WIDTH*4;
   self->eg.g.Height           = Height   - Y_BORDER_WIDTH*4;
   self->eg.g.GadgetRender     = (APTR) &(self->AutoKnob);
   self->eg.g.SelectRender     = NULL;
   self->eg.g.SpecialInfo      = (APTR) &(self->Prop);

   self->Prop.Flags       = AUTOKNOB | PROPBORDERLESS | V36_PROPNEWLOOK;
   self->Prop.HorizPot    = 0x8000;
   self->Prop.VertPot     = 0x8000;
   self->Prop.HorizBody   = 0xFFFF;
   self->Prop.VertBody    = 0xFFFF;
   self->Prop.CWidth      = 0;
   self->Prop.CHeight     = 0;
   self->Prop.HPotRes     = 0;
   self->Prop.VPotRes     = 0;
   self->Prop.LeftBorder  = 0;
   self->Prop.TopBorder   = 0;

   SetLocation( self, LeftEdge, TopEdge );
   SetSize    ( self, Width, Height );
}


void SlideLower( Slider *self )
{
   long    position;
   USHORT   delta, value;

   delta = KnobSize( self ) /2;
   delta = MAX( delta, 1 );

   value = Value(self);
   position = value - delta;
   position = MAX( position, 0 );

   SetValue( self, position );
}


void SlideHigher( Slider *self )
{
   ULONG  position;
   USHORT delta;
   USHORT value;

   delta = KnobSize( self ) /2;
   delta = MAX( delta, 1 );
   value = Value(self);

   position = value + delta;
   position = MIN( position, 0xFFFF );

   SetValue( self, position );
}

