#include <intuition/intuisup.h>

#define TEXT_AREA    100
#define FONTS_NUM    2

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct DiskFontBase  *DiskfontBase;

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


struct   TextAttr Attribute[2];
struct   TextFont *Font[2];
struct   Window   *window[2];
struct   TextArea *textarea[2];
UBYTE    Title[2][40] =
   {
   "Sample Topaz 8 Text Area",
   "Sample Helvetica 13 Text Area"
   };


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  = "topaz.font";
   Attribute[0].ta_YSize = 8;
   Attribute[1].ta_Name  = "helvetica.font";
   Attribute[1].ta_YSize = 13;

   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   mouse_x, mouse_y, area;
   APTR     address;
   struct   IntuiMessage *message;
   struct   Window       *w;

   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;

   window[0] = OpenStdWindow(Title[0], 0x1F, 15,20,350,150, NULL);
   window[1] = OpenStdWindow(Title[1], 0x17, 35,43,350,150, NULL);
   ModifyIDCMP(window[0],  CLOSEWINDOW | GADGETDOWN | NEWSIZE);
   ModifyIDCMP(window[1],  GADGETDOWN | NEWSIZE);

   if (!LoadFonts()) { rc = 20; goto MAIN_DONE; }
   if (!window[0])   { rc = 30; goto MAIN_DONE; }
   if (!window[1])   { rc = 40; goto MAIN_DONE; }

   /* 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[0]->RPort, Font[0]);
   SetFont(window[1]->RPort, Font[1]);
   textarea[0]=OpenTextArea(window[0], 6,12,(USHORT)(window[0]->Width-11),(USHORT)(window[0]->Height-15), TEXT_AREA, -1, 0);
   textarea[1]=OpenTextArea(window[1], 6,12,(USHORT)(window[1]->Width-11),(USHORT)(window[1]->Height-15), TEXT_AREA, -1, 0);

   if (!textarea[0] || !textarea[1]) { rc = 50; goto MAIN_DONE; }

   /* 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, "");                               */
   AddTextAreaLine(textarea[0], -1, "This font is non proportional.", LN_PARAGRAPH_BEGIN);
   RefreshTextArea(textarea[0]);
   AddTextAreaLine(textarea[1], -1, "This font is proportional.", LN_PARAGRAPH_BEGIN);
   AddTextAreaLine(textarea[1], -1, "Try typing some text and scrolling around!", LN_PARAGRAPH_BEGIN);
   RefreshTextArea(textarea[1]);

   /* Force editing into the second 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's that?                            */
   EditTextArea(textarea[1], 1000, 1000);

   FOREVER
         {
         /* DO NOT take this as an example for a good control loop!!    */
         /* I just dont have time make the windows share their port.    */
         Wait( (window[0]? (1<<window[0]->UserPort->mp_SigBit) : 0)
             | (window[1]? (1<<window[1]->UserPort->mp_SigBit) : 0) );

         while (  (message=(window[0]? GetMsg(window[0]->UserPort) : NULL))
               || (message=(window[1]? GetMsg(window[1]->UserPort) : NULL)) )
               {
               class   = message->Class;
               address = message->IAddress;
               mouse_x = message->MouseX;
               mouse_y = message->MouseY;
               w       = message->IDCMPWindow;
               ReplyMsg(message);

               /* Get the right window pointer back.       */
               /* This is screwy, but... it works (sight!) */
               area = (w==window[0]? 0 : 1);

               switch(class)
                     {
                     case CLOSEWINDOW: goto MAIN_DONE;

                     case GADGETDOWN:
                     /* here we go to the actual editing. As you can   */
                     /* see, it's not too complicated.                 */
                        if (((struct Gadget *)address)->GadgetID==TEXT_AREA)
                           EditTextArea(textarea[area], mouse_x, mouse_y);
                     break;

                     case NEWSIZE:
                        SetPointerNum(w, WAIT_POINTER);
                        RemakeStdWindow(w, Title[area]);
                        textarea[area]->Width  = w->Width- 11;
                        textarea[area]->Height = w->Height-15;
                        RethinkTextArea(textarea[area], 0);
                        SetPointerNum(w, WBENCH_POINTER);
                        EditTextArea(textarea[area], -1, -1);
                     break;
                     }
               }
         }

   MAIN_DONE:
        for (area=0; area<2; area++)
            {
            if (textarea[area])   CloseTextArea(textarea[area]);
            if (window[area])     CloseStdWindow(window[area]);
            }

#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);
}

