#include <intuition/intuisup.h>

#define TEXT_AREA1   0     /* these area the gadgetIds for the text areas  */
#define TEXT_AREA2   1
#define TEXT_AREA3   2
#define TEXT_AREA4   3
#define TEXT_AREA5   4

#define AREAS_NUM    5     /* total number of areas                        */
#define FONTS_NUM    3     /* total number of fonts                        */

extern USHORT CommentsData[];
struct Image  CommentsImage = { 0,0, 167,146, 2, CommentsData, 0x1,0x0, NULL };
struct Box    box = { NULL, 182,15, 254,19, 0,1,0,2, "", BOX_SHADING };

struct Library *IntuitionBase, *GfxBase, *DiskfontBase;

#ifdef ISUP_RUNTIME
struct   Library  *iSupBase;
#else
struct   Device   *ConsoleDevice;
struct   IOStdReq  ConsoleMsg;
#endif

struct   TextAttr Attribute[FONTS_NUM];
struct   TextFont *Font[FONTS_NUM];
struct   TextArea *textarea[AREAS_NUM];
struct   Window   *window;


BOOL
LoadFonts()
{
   extern struct   TextFont *OpenFont(), *OpenDiskFont();

   USHORT   i;

   /* Just change these attributes to get new fonts in the text areas,  */
   /* they will adapt to any font (as long as it's left->right one)     */
   Attribute[0].ta_Name  = "courier.font";
   Attribute[0].ta_YSize = 15;
   Attribute[1].ta_Name  = "courier.font";
   Attribute[1].ta_YSize = 13;
   Attribute[2].ta_Name  = "courier.font";
   Attribute[2].ta_YSize = 11;

   for(i=0; i<FONTS_NUM; i++)
      {
      if (  !(Font[i]=OpenFont(&Attribute[i]))
         || (Font[i]->tf_YSize!=Attribute[i].ta_YSize) )
         {
         if (!(Font[i]=OpenDiskFont(&Attribute[i])))
            {
            DisplayBeep(NULL);
            return(FALSE);
            }
         }
      }
   return(TRUE);
}

VOID main(argc, argv)
LONG argc;
char **argv;
{
   extern struct IntuiMessage *GetMsg();
   extern struct Window       *OpenStdWindow();

   UBYTE    rc = 0;
   LONG     class;
   USHORT   id, mouse_x, mouse_y, area;
   APTR     address;
   struct   IntuiMessage *message;

   if (  !(GfxBase       = (struct Library *)OpenLibrary("graphics.library", 0))
      || !(IntuitionBase = (struct Library *)OpenLibrary("intuition.library", 0))
      || !(DiskfontBase  = (struct Library *)OpenLibrary("diskfont.library", 0))
#ifdef ISUP_RUNTIME
      || !(iSupBase      = (struct Library *)OpenLibrary("isup.library", 0))
#else
      || !(!OpenDevice("console.device", -1, &ConsoleMsg, 0) && (ConsoleDevice=ConsoleMsg.io_Device))
#endif
      ) goto MAIN_DONE;

   if (!LoadFonts()) { rc = 20; goto MAIN_DONE; }
   if (!(window=OpenStdWindow("Mask editing with iSup Text Areas", 0x1B, 10,20, 450,167, NULL)))
      { rc = 30; goto MAIN_DONE; }
   ModifyIDCMP(window,  CLOSEWINDOW | GADGETDOWN | NEWSIZE);

   /* Prepare the windows for text areas. Set the colors (already done) */
   /* and the fonts. Note that we leave a little room around the text   */
   /* areas: this is safer in case some character have fancy kerning -  */
   /* for instance 'u' as -1 in Times 18 and will come out of the area  */
   /* by one pixel towards the left if it appears first on a line.      */
   SetFont(window->RPort, Font[0]);
   textarea[0]=OpenTextArea(window, 186,17, 246,16, TEXT_AREA1, 1, TA_CENTER_JUSTIFY);
   DrawBox(window->RPort, &box, 0,0);

   SetFont(window->RPort, Font[1]);
   textarea[1]=OpenTextArea(window, 184,40, 253,14, TEXT_AREA2,  1, TA_ARYTHMETIC);
   textarea[2]=OpenTextArea(window, 184,60, 253,28, TEXT_AREA3,  2, 0);

   SetFont(window->RPort, Font[2]);
   textarea[3]=OpenTextArea(window, 184,94, 253,24, TEXT_AREA4,  3, TA_WORD_MODE);
   textarea[4]=OpenTextArea(window, 184,124,253,36, TEXT_AREA5, -1, TA_WORD_MODE);

   for(area=0; area<AREAS_NUM; area++)
      if (!textarea[area]) { rc = 50+area; goto MAIN_DONE; }

   /* Link the areas together. This enables the user to move from one   */
   /* area to another with the cursor keys when he reaches an end.      */
   LinkTextArea(textarea[0], NULL, textarea[1]);
   LinkTextArea(textarea[AREAS_NUM-1], textarea[AREAS_NUM-2], NULL);
   for(area=1; area<AREAS_NUM-1; area++)
      LinkTextArea(textarea[area], textarea[area-1], textarea[area+1]);

   /* Place some text in the text areas. You should ALWAYS place some   */
   /* text in a text area. They are returned with 0 acitves lines, and  */
   /* must have at least one line to be usable. If no text is wanted    */
   /* upon startup, you MUST use the following:                         */
   /*    AddTextAreaLine(myarea, -1, "", LN_PARAGRAPH_BEGIN);           */
   /* We also specify here which areas have a limited number of lines,  */
   /* the default upon opening being unlimited lines.                   */
   AddTextAreaLine(textarea[0], -1, "Gauthier Groult", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[1], -1, "(1) 47 89 09 54", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[2], -1, "groult@germinal.ibp.fr", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[2], -1, "groult@cbmfra", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[3], -1, "33, Blvd Saint Denis", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[3], -1, "92400 Courbevoie", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[3], -1, "France - Europe", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[4], -1, "Born on March 11, 1966.", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[4], -1, "Enjoys windsurfing, surfing, snowboarding, skiing & speedsailing.", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[4], -1, "Plays the guitar, pronounced blues influence.", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[4], -1, "Likes blond, tall, well balanced girls.", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[4], -1, "Speaks and writes French, English and Italian. Basic knowledge of Russian.", LN_PARAGRAPH_BEGIN);

   for(area=0; area<AREAS_NUM; area++) RefreshTextArea(textarea[area]);

   DrawImage(window->RPort, &CommentsImage, 10, 15);

   /* Force editing into the first area with some fake mouse coords     */
   /* that will posiion the cursor at the end of the text               */
   /* We come back from here whenever the user does anything else then  */
   /* editing (clicking somewhere outside the area, pulling a menu or   */
   /* anything else), and the message that caused the exit will be left */
   /* on our port transparently. How about it?                          */
   EditTextArea(textarea[0], 1000, 1000);

   FOREVER
      {
      WaitPort(window->UserPort);

      while (message = GetMsg(window->UserPort))
            {
            class   = message->Class;
            address = message->IAddress;
            mouse_x = message->MouseX;
            mouse_y = message->MouseY;
            ReplyMsg(message);

            switch(class)
                  {
                  case CLOSEWINDOW: goto MAIN_DONE; break;

                  case GADGETDOWN:
                  /* here we go to the actual editing. As you can   */
                  /* see, its not too complicated!                  */
                  id = ((struct Gadget *)address)->GadgetID;
                  if (id >= TEXT_AREA1 && id <=TEXT_AREA5)
                     EditTextArea(textarea[id], mouse_x, mouse_y);
                  break;
                  }
            }
      }

   MAIN_DONE:
      for(area=0; area<AREAS_NUM; area++)
         if (textarea[area])   CloseTextArea(textarea[area]);

      if (window)       CloseStdWindow(window);

#ifdef ISUP_RUNTIME
      if (iSupBase)      CloseLibrary(iSupBase);
#else
      if (ConsoleDevice) CloseDevice(&ConsoleMsg);
#endif
      if (DiskfontBase)  CloseLibrary(DiskfontBase);
      if (IntuitionBase) CloseLibrary(IntuitionBase);
      if (GfxBase)       CloseLibrary(GfxBase);
      exit(rc);
}

