#define __USE_SYSBASE 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dos.h>
#include <dos/dos.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <pragmas/blitzblank_pragmas.h>

#include <BlitzBlank.h>

struct Library *BlitzBlankBase;
static const char version[]="$VER: BB.Lines 2.51 (06.03.94)";

char *text[]={"\33c\33uLines\33n\n\nModule for BlitzBlank\n\nCopyright 1995\nby\nThomas Börkel",
              "_Lines:" };

struct BB_Object object[]={ {&object[1],BB_VGroup,0,0,0,NULL,NULL},
                            {&object[2],BB_Slider,5,200,50,NULL,NULL},
                            {NULL      ,BB_VGroup_End,0,0,0,NULL,NULL} };

struct line
{
  int x1;
  int y1;
  int x2;
  int y2;
  int c;
};


struct BB_Message message;
struct BB_Screeninfo *screeninfo;
struct RastPort *rp;
struct line *li;
int dx1,dy1,dx2,dy2;


int sgn (long a)
{
  if (a<0)
    return (-1);
  if (a>0)
    return (1);
  return (0);
}


void check (int i)
{
  if (li[i].x1>screeninfo->width-1 || li[i].x1<0)
  {
    dx1=-dx1;
    li[i].x1+=2*dx1;
  }
  if (li[i].y1>screeninfo->height-1 || li[i].y1<0)
  {
    dy1=-dy1;
    li[i].y1+=2*dy1;
  }
  if (li[i].x2>screeninfo->width-1 || li[i].x2<0)
  {
    dx2=-dx2;
    li[i].x2+=2*dx2;
  }
  if (li[i].y2>screeninfo->height-1 || li[i].y2<0)
  {
    dy2=-dy2;
    li[i].y2+=2*dy2;
  }
  return;
}


void blank (void)
{
  int i,colors,al,w=3,s=1,co=1,ch,stop=FALSE,v;
  struct ViewPort *vp;
  struct DateStamp ds;

  al=object[1].set;

  if (!(li=calloc (al+1,sizeof (struct line)))) return;

  colors=1<<screeninfo->depth;
  rp=&screeninfo->bbscreen->RastPort;
  vp=&screeninfo->bbscreen->ViewPort;

  DateStamp (&ds);
  srand48 (ds.ds_Minute*60+ds.ds_Tick);

  SetRGB4 (vp,0,0,0,0);
  SetRGB4 (vp,1,15,0,0);
  if (colors>2)
  {
    SetRGB4 (vp,2,0,0,15);
    SetRGB4 (vp,3,0,15,0);
    if (colors>4)
    {
      SetRGB4 (vp,4,0,5,0);
      SetRGB4 (vp,5,15,3,8);
      SetRGB4 (vp,6,15,5,15);
      SetRGB4 (vp,7,5,15,8);
      if (colors>8)
      {
        SetRGB4 (vp,8,10,5,0);
        SetRGB4 (vp,9,0,15,5);
        SetRGB4 (vp,10,15,7,15);
        SetRGB4 (vp,11,0,7,15);
        SetRGB4 (vp,12,8,15,3);
        SetRGB4 (vp,13,15,10,5);
        SetRGB4 (vp,14,7,0,15);
        SetRGB4 (vp,15,3,8,15);
        if (colors>16)
          for (i=16;i<colors;i++)
            SetRGB4 (vp,i,(long) (drand48 ()*13+3),(long) (drand48 ()*13+3),(long) (drand48 ()*13+3));
      }
    }
  }

  ch=al/colors;
  if (ch==0)
    ch=1;

  dx1=drand48 ()*w+s;
  dy1=drand48 ()*w+s;
  dx2=drand48 ()*w+s;
  dy2=drand48 ()*w+s;

  li[0].x1=drand48 ()*screeninfo->width;
  li[0].y1=drand48 ()*screeninfo->height;
  li[0].x2=drand48 ()*screeninfo->width;
  li[0].y2=drand48 ()*screeninfo->height;

  ScreenToFront (screeninfo->bbscreen);

  if (!CheckSignal (SIGBREAKF_CTRL_C))
  {
    BBL_ModuleRunning ();

    for (i=1;i<al;i++)
    {
      li[i].x1=li[i-1].x1+dx1;
      li[i].y1=li[i-1].y1+dy1;
      li[i].x2=li[i-1].x2+dx2;
      li[i].y2=li[i-1].y2+dy2;
      check (i);
      if (i%ch==0)
      {
        co++;
        if (co>colors-1)
          co=1;
      }
      SetAPen (rp,co);
      Move (rp,li[i].x1,li[i].y1);
      Draw (rp,li[i].x2,li[i].y2);
      if (CheckSignal (SIGBREAKF_CTRL_C))
      {
        i=al-1;
        stop=TRUE;
      }
    }

    if (!stop && !CheckSignal (SIGBREAKF_CTRL_C))
    {
      i=0;
      v=al-1;
      do
      {
        SetAPen (rp,0);
        Move (rp,li[i].x1,li[i].y1);
        Draw (rp,li[i].x2,li[i].y2);
        li[i].x1=li[v].x1+dx1;
        li[i].y1=li[v].y1+dy1;
        li[i].x2=li[v].x2+dx2;
        li[i].y2=li[v].y2+dy2;
        check (i);
        if (i%ch==0)
        {
          co++;
          if (co>colors-1)
            co=1;
        }
        SetAPen (rp,co);
        Move (rp,li[i].x1,li[i].y1);
        Draw (rp,li[i].x2,li[i].y2);
        i++;
        if (i>al-1)
        {
          i=0;
          dx1=sgn(dx1)*(drand48 ()*w+s);
          dy1=sgn(dy1)*(drand48 ()*w+s);
          dx2=sgn(dx2)*(drand48 ()*w+s);
          dy2=sgn(dy2)*(drand48 ()*w+s);
        }
        v++;
        if (v>al-1)
          v=0;
      } while (!CheckSignal (SIGBREAKF_CTRL_C));
    }
  }
  return;
}


void main(int argc,char **argv)
{

  if (!(BlitzBlankBase=OpenLibrary ("blitzblank.library",BLITZBLANKLIB_VER)))
    exit (0);

  message.flags=BBF_Screenmode|BBF_Colors;
  message.first=&object[0];
  StrToLong (argv[3],(long *) &screeninfo);
  screeninfo->maxdepth=4;

  if (strcmp (argv[1],"BLANK")==0)
  {
    BBL_SendMessage (&message,argv[2]);
    if (screeninfo->bbscreen)
      blank ();
    BBL_BlankDone ();
  }
  else
  {
    message.infotext=BBL_GetString (270,text[0]);
    object[1].label=BBL_GetString (271,text[1]);
    if (strcmp (argv[1],"CONFIG")==0)
    {
      BBL_SendMessage (&message,argv[2]);
    }
    else
    {
      message.first=NULL;
      BBL_SendMessage (&message,argv[2]);
    }
  }
  CloseLibrary (BlitzBlankBase);
  exit (0);
}

