;/* dragtest.c - Test for the gtdrag.library, 6.11.1996
;**
;** (C) Copyright 1996 Axel Dörfler
;**     All rights reserved
;**
sc dragtest.c link ign=73 data=near nodbg parm=b nochkabort nostkchk strmer streq to=ram:dragtest
run ram:dragtest
quit
*/

#define INTUI_V36_NAMES_ONLY

#include <exec/libraries.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <libraries/gadtools.h>
#include <libraries/gtdrag.h>
#include <libraries/asl.h>
#include <dos/dos.h>

#include <clib/alib_protos.h>
#include <clib/alib_stdio_protos.h>
#include <clib/gtdrag_protos.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/layers.h>
#include <proto/utility.h>
#include <proto/dos.h>
#include <pragmas/gtdrag_pragmas.h>

#include <stdlib.h>
#include <ctype.h>
#include <string.h>

void main(int, char **);

#define TLn(t) TextLength(&scr->RastPort,t,strlen(t))

UWORD chip newImgData[52] =
{
        /* Plane 0 */
        0x0000,0x0020,0x3FFF,0xFFE0,0x3FFF,0xFFE0,0x3FFF,0xFFE0,
        0x3FFF,0xFFE0,0x3FFF,0xFFE0,0x3FFF,0xFFE0,0x3FFF,0xFFE0,
        0x3FFF,0xFFE0,0x3FFF,0xFFE0,0x3FFF,0xFFE0,0x3FFF,0xFFE0,
        0x7FFF,0xFFE0,
        /* Plane 1 */
        0xFFFF,0xFFC0,0xFFFF,0xFF80,0xF3BF,0xFF80,0xF3BF,0xFF80,
        0xF5B3,0x6D80,0xF5AD,0x6D80,0xF6A1,0xAB80,0xF6AF,0xAB80,
        0xF72D,0xD780,0xF733,0xD780,0xFFFF,0xFF80,0xFFFF,0xFF80,
        0x8000,0x0000
};

struct Image newImg = {0,0,27,13,2,newImgData,0x0003,0x0000,NULL};

struct Screen *scr;
struct Window *win;
struct IntuiMessage imsg;
struct Library *GTDragBase;
struct Gadget *glist,*lvgad[2],*gad[3];
struct NewGadget ng;
struct List list[2];
struct Node *node;
struct ImageNode in;
APTR   vi;
int    fontheight;
BOOL   ende = FALSE;


void InsertAt(struct List *l,struct Node *n,int pos)
{
  struct Node *pn;
  int    i;

  if (pos)
  {
    pos--;
    for(pn = l->lh_Head,i = 0;i<pos;pn = pn->ln_Succ,i++);
    Insert(l,n,pn);
  }
  else
    AddHead(l,n);
}


void MoveTo(struct Node *n,struct List *l1,int pos1,struct List *l2,int pos2)
{
  struct Node *pn;
  int    i;

  if (l1 == l2 && pos1 == pos2)
    return;
  Remove(n);

  if (pos2)
  {
    pos2--;
    for(pn = l2->lh_Head,i = 0;i<pos2;pn = pn->ln_Succ,i++);
    Insert(l2,n,pn);
  }
  else
    AddHead(l2,n);
}


void processMsg(void)
{
  struct IntuiMessage *msg;
  struct DragMsg *dm;
  int source,target;

  while(!ende)
  {
    WaitPort(win->UserPort);
    while(msg = GTD_GetIMsg(win->UserPort))
    {
      imsg = *msg;
      GTD_ReplyIMsg(msg);

      if (dm = GTD_GetDragMsg())
      {
        if (dm->dm_SourceApp)
        {
          DisplayBeep(NULL);
        }
        else
        {
          switch(dm->dm_Type)
          {
            case DMT_GADGET:
              target = ((struct DragGadget *)dm->dm_Target)->dg_Gadget->GadgetID;
              switch(target)
              {
                case 1:
                case 2:
                  source = dm->dm_Source->dg_Gadget->GadgetID;
                  if (source<3)
                  {
                    source--;  target--;
                    GT_SetGadgetAttrs(lvgad[0],win,NULL,GTLV_Labels,~0L,TAG_END);
                    GT_SetGadgetAttrs(lvgad[1],win,NULL,GTLV_Labels,~0L,TAG_END);
                    MoveTo((APTR)dm->dm_Object,&list[source],dm->dm_SourceEntry,&list[target],dm->dm_TargetEntry);
                    GT_SetGadgetAttrs(lvgad[0],win,NULL,GTLV_Labels,&list[0],TAG_END);
                    GT_SetGadgetAttrs(lvgad[1],win,NULL,GTLV_Labels,&list[1],TAG_END);
                  }
                  else
                  {
                    target--;
                    GT_SetGadgetAttrs(lvgad[target],win,NULL,GTLV_Labels,~0L,TAG_END);
                    if (node = AllocMem(sizeof(struct Node),MEMF_CLEAR | MEMF_PUBLIC))
                    {
                      node->ln_Name = in.in_Name;
                      InsertAt(&list[target],node,dm->dm_TargetEntry);
                    }
                    GT_SetGadgetAttrs(lvgad[target],win,NULL,GTLV_Labels,&list[target],TAG_END);
                  }
                  break;
                case 3:
                  DisplayBeep(NULL);
                  break;
                case 4:
                case 5:
                  source = dm->dm_Source->dg_Gadget->GadgetID-1;
                  GT_SetGadgetAttrs(lvgad[source],win,NULL,GTLV_Labels,~0L,TAG_END);
                  if (target==4)
                  {
                    if (node = AllocMem(sizeof(struct Node),MEMF_CLEAR | MEMF_PUBLIC))
                    {
                      node->ln_Name = dm->dm_Object->in_Name;
                      AddTail(&list[source],node);
                     }
                  }
                  else
                  {
                    Remove((struct Node *)dm->dm_Object);
                    FreeMem(dm->dm_Object,sizeof(struct Node));
                  }
                  GT_SetGadgetAttrs(lvgad[source],win,NULL,GTLV_Labels,&list[source],TAG_END);
                  break;
              }
              break;
            case DMT_UNKNOWN:
              DisplayBeep(NULL);
              break;
            case DMT_WINDOW:
              break;
          }
        }
        GTD_ReplyDragMsg(dm);
      }
      switch(imsg.Class)
      {
        case IDCMP_GADGETDOWN:
          break;
        case IDCMP_GADGETUP:
          switch(((struct Gadget *)imsg.IAddress)->GadgetID)
          {
            case 3:
              GT_SetGadgetAttrs(lvgad[0],win,NULL,GTLV_Labels,~0L,TAG_END);
              if (node = AllocMem(sizeof(struct Node),MEMF_CLEAR | MEMF_PUBLIC))
              {
                node->ln_Name = in.in_Name;
                AddTail(&list[0],node);
              }
              GT_SetGadgetAttrs(lvgad[0],win,NULL,GTLV_Labels,&list[0],TAG_END);
              break;
          }
          break;
        case IDCMP_CLOSEWINDOW:
          ende = TRUE;
          break;
      }
    }
  }
}

const STRPTR txt[] = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"};

struct Window *initWindow(void)
{
  struct Window *win;

  gad[0] = CreateContext(&glist);

  ng.ng_LeftEdge = 8;
  ng.ng_TopEdge = fontheight+7;
  ng.ng_Width = 192;
  ng.ng_Height = 11*fontheight+4;
  ng.ng_VisualInfo = vi;
  ng.ng_TextAttr = scr->Font;
  ng.ng_GadgetText = NULL;
  ng.ng_UserData = NULL;
  ng.ng_GadgetID = 1;
  lvgad[0] = CreateGadget(LISTVIEW_KIND,gad[0],&ng,GTLV_Labels,&list[0],TAG_END);

  ng.ng_LeftEdge = 206;
  ng.ng_Width = 186;
  ng.ng_GadgetText = NULL;
  ng.ng_GadgetID++;
  lvgad[1] = CreateGadget(LISTVIEW_KIND,lvgad[0],&ng,GTLV_Labels,&list[1],TAG_END);

  ng.ng_TopEdge += ng.ng_Height+3;
  ng.ng_LeftEdge = 8;
  ng.ng_Height = fontheight+4;
  ng.ng_Width = TLn("New")+16;
  ng.ng_Flags = PLACETEXT_IN;
  ng.ng_GadgetText = "New";
  ng.ng_GadgetID++;
  gad[0] = CreateGadget(BUTTON_KIND,lvgad[1],&ng,GA_Immediate,TRUE,TAG_END);

  ng.ng_LeftEdge += ng.ng_Width+6;
  ng.ng_Width = TLn("Copy")+16;
  ng.ng_GadgetText = "Copy";
  ng.ng_GadgetID++;
  gad[1] = CreateGadget(BUTTON_KIND,gad[0],&ng,TAG_END);

  ng.ng_LeftEdge += ng.ng_Width+6;
  ng.ng_Width = TLn("Delete")+16;
  ng.ng_GadgetText = "Delete";
  ng.ng_GadgetID++;
  gad[2] = CreateGadget(BUTTON_KIND,gad[1],&ng,TAG_END);

  if (win = OpenWindowTags(NULL,WA_Title,   "gtdrag - Test",
                                WA_Flags,   WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE,
                                WA_IDCMP,   IDCMP_CLOSEWINDOW | DRAGIDCMP,
                                WA_Width,   400,
                                WA_Height,  fontheight*13+23,
                                WA_Gadgets, glist,
                                TAG_END))
  {
    GT_RefreshWindow(win,NULL);
    GTD_AddGadget(LISTVIEW_KIND,lvgad[0],win,GTDA_Mask,1,GTDA_Same,TRUE,TAG_END);
    GTD_AddGadget(LISTVIEW_KIND,lvgad[1],win,GTDA_Mask,1,GTDA_Same,TRUE,TAG_END);
    GTD_AddGadget(BUTTON_KIND,gad[0],win,GTDA_Images,TRUE,GTDA_Object,     &in,
                                                          GTDA_Mask,       2,
                                                          GTDA_AcceptMask, 0,
                                                          GTDA_Width,      newImg.Width,
                                                          GTDA_Height,     newImg.Height,
                                                          TAG_END);
    GTD_AddGadget(BUTTON_KIND,gad[1],win,GTDA_AcceptMask,1,TAG_END);
    GTD_AddGadget(BUTTON_KIND,gad[2],win,GTDA_AcceptMask,1,TAG_END);
    GTD_AddWindow(win,TAG_END);
    return(win);
  }
  return(NULL);
}


void init(void)
{
  int i;

  NewList(&list[0]);
  NewList(&list[1]);
  for(i = 0;i<20;i++)
  {
    if (node = AllocMem(sizeof(struct Node),MEMF_CLEAR | MEMF_PUBLIC))
    {
      node->ln_Name = txt[i];
      AddTail(&list[0],node);
    }
  }
  in.in_Name = "** New **";
  in.in_Image = &newImg;
}


void main(int argc, char **argv)
{
  if (GTDragBase = OpenLibrary("gtdrag.library",2))
  {
    if (GTD_AddAppA("dragtest",NULL))
    {
      if (scr = LockPubScreen(NULL))
      {
        vi = GetVisualInfo(scr,TAG_END);
        fontheight = scr->Font->ta_YSize;
        init();

        if (win = initWindow())
        {
          processMsg();
          CloseWindow(win);
        }

        FreeVisualInfo(vi);
        UnlockPubScreen(NULL,scr);
      }
      GTD_RemoveApp();
    }
    CloseLibrary(GTDragBase);
  }
}
