/*
 *  SCALEBAR.C
 */

#include "newlook.h"

extern void CopyMem(APTR,APTR,ULONG);
extern VOID DrawImage( struct RastPort *, struct Image *, WORD, WORD );
extern VOID DrawBorder( struct RastPort *, struct Border *, WORD, WORD );

struct ScalebarInfo *CreateScalebar(x,y,w,h, nmin,nmax)
SHORT x,y,w,h;
LONG nmin, nmax;
{
  struct ScalebarInfo *si;
  struct Image *i;
  struct Border *b;

  ULONG UserHandle= SetNewLookHandle(PRIVATE_HANDLE);

  if(si= (struct ScalebarInfo *)SmartAllocate(SCALEBARINFOSIZE))
  {
    if(i= (struct Image *)SmartAllocate(3*IMAGESIZE))
    {
      if(w < SCALEBARHMIN) w= SCALEBARHMIN;
      if(h < SCALEBARVMIN) h= SCALEBARVMIN;

      if(b= (struct Border *)CreateBorder(x,y, w,h, FALSE))
      {
        long r= nmax - nmin;  /* range */

        si->wmin        = (nmin<0) ? (nmin*(w-8)+r/2)/r : 0L;
        si->wmax        = (LONG)w-8 + si->wmin;
        si->outline     = b;
        si->scalebar    = &i[0];
        si->nmin        = nmin;
        si->nmax        = nmax;

        i[0].TopEdge    = y+2;
        i[0].Height     = h-4;
        i[0].Depth      = 0;
        i[0].ImageData  = (UWORD *)NULL;
        i[0].PlanePick  = 0x00;

        CopyMem((APTR)&i[0],(APTR)&i[1],IMAGESIZE);
        CopyMem((APTR)&i[0],(APTR)&i[2],IMAGESIZE);

        i[0].LeftEdge   = x+2;
        i[0].PlaneOnOff = 0;
        i[0].NextImage  = &i[1];

        i[1].PlaneOnOff = SCALEBARPEN;   /* trick! */
        i[1].NextImage  = &i[2];

        i[2].PlaneOnOff = 0;
        i[2].NextImage  = (struct Image *)NULL;

        MakePrivateHandlePublic(UserHandle);
        return si;
      }
    }
  }
  if(UserHandle != PRIVATE_HANDLE)
  { SmartFreeAll(PRIVATE_HANDLE);
    (void)SetNewLookHandle(UserHandle);
  }
  return (struct ScalebarInfo *)NULL;
}


void SetScalebar(w,si,n)
struct Window *w;
struct ScalebarInfo *si;
LONG n;
{
  struct Image *i;

  if(si && (i= si->scalebar))
  {
    LONG N= si->nmax - si->nmin;  /* numerical range */
    LONG G= si->wmax - si->wmin;  /* graphical range */

    LONG W= (n * G + N/2) / N;    /* blue bar's width */

    if(W < si->wmin) W= si->wmin;
    else if(W > si->wmax) W= si->wmax;

    /*printf("%ld <= (W=%ld) <= %ld\n",si->wmin,W,si->wmax);*/

    i[0].Width= 2 - si->wmin + ( (W<0) ? W:0 );
    i[1].LeftEdge= i[0].LeftEdge + i[0].Width;
    i[1].Width= ( (W<0) ? -W : W );
    i[2].LeftEdge= i[1].LeftEdge + i[1].Width;
    i[2].Width= G - i[0].Width - i[1].Width + 4;

    DrawImage(w->RPort, i, 0,0);
    DrawBorder(w->RPort, si->outline, 0,0);
  }
}
