;/*
   Avail Flush >NIL:
   MakeClass Text VER 3 REV 82 ;ASM
   Quit
*/

///Header
#include <string.h>

#include <graphics/text.h>
#include <libraries/feelin.h>

#include <clib/utility_protos.h>
#include <clib/exec_protos.h>
#include <clib/feelin_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/utility_pragmas.h>

UBYTE FCC_Name[] = FC_Text;
UBYTE FCC_ID[]   = "$VER: FC_Text 3.82 (07-04-02) by Olivier Laviale (lotan9@aol.com)";

struct Library       *DOSBase,*UtilityBase;
struct FeelinBase    *FeelinBase;

struct LocalObjectData
{
   ULONG                      nFlags;
   STRPTR                     pcText;
   STRPTR                     pcPrep[2];
   struct FeelinTextDisplay  *TextDisplay;
};

#define  FF_Text_HCenter  (1L << 00)
#define  FF_Text_VCenter  (1L << 01)
#define  FF_Text_Static   (1L << 02)
#define  FF_Text_SetMin   (1L << 03)

//+

///Text_New
ULONG SAVEDS Text_New(struct FeelinClass *Class,APTR Obj,struct LocalObjectData *LOD,struct TagItem *Tags)
{
   struct TagItem *item;

   LOD -> nFlags = (FF_Text_HCenter | FF_Text_SetMin | FF_Text_Static);

/*

The TextDisplay object should be created before calling  our  super  class,
remember that when the method FM_New reaches FC_Object the method FM_Set is
invoked on the object with the same taglist. It's useful as  each  subclass
don't  have  to  call  its  custom  Class.Set,  but  if an attribute is set
directly to an object the objet must be allocated first  or  the  attribute
will have no effect.

*/

   if (LOD -> TextDisplay = F_NewObjA(FC_TextDisplay,Tags))
   {
      if (F_SuperDoA(Class,Obj,FM_New,(ULONG *)Tags))
      {
         while (item = NextTagItem(&Tags))
         {
            switch (item -> ti_Tag)
            {
               case FA_Text_SetMin:    LOD -> nFlags = item -> ti_Data ? (LOD -> nFlags | FF_Text_SetMin)   : (LOD -> nFlags - (LOD -> nFlags & FF_Text_SetMin));   break;
            }
         }
         return (ULONG) Obj;
      }
   }
   return NULL;
}
//+
///Text_Dispose
ULONG SAVEDS Text_Dispose(struct FeelinClass *Class,APTR Obj,struct LocalObjectData *LOD,ULONG *Args)
{
   LOD -> TextDisplay = (struct FeelinTextDisplay *) F_DisposeObj(LOD -> TextDisplay);

   if ((FF_Text_Static & LOD -> nFlags) == NULL)
   {
      LOD -> pcText = (STRPTR) F_Dispose(LOD -> pcText);
   }
   return F_SuperDoA(Class,Obj,FM_Dispose,Args);
}
//+
///Text_Set
ULONG SAVEDS Text_Set(APTR Obj,struct LocalObjectData *LOD,struct TagItem *Tags)
{
   struct TagItem *item;
   ULONG  temp;

   while (item = NextTagItem(&Tags))
   {
      switch (item -> ti_Tag)
      {
         case FA_Text:
            if (FF_Text_Static & LOD -> nFlags)
            {
               LOD -> pcText = (UBYTE *)item -> ti_Data;
            }
            else
            {
               LOD -> pcText = (UBYTE *)F_Dispose(LOD -> pcText);

               if (item -> ti_Data)
               {
                  if (temp = strlen((char const *)item -> ti_Data))
                  {
                     if (LOD -> pcText = F_New(temp+1))
                     {
                        CopyMem((APTR)item -> ti_Data,LOD -> pcText,temp);
                     }
                  }
               }
            }

            F_Set(LOD -> TextDisplay,FA_Text,(ULONG)LOD -> pcText);

            if (temp = F_Get(LOD -> TextDisplay,FA_TextDisplay_UnderShort))
            {
                F_Set(Obj,FA_ControlChar,temp);
            }

            F_Draw(Obj,FF_Draw_Update);
         break;

         case FA_Text_PreParse:     LOD -> pcPrep[0] = (APTR)item -> ti_Data; break;
         case FA_Text_AltPreParse:  LOD -> pcPrep[1] = (APTR)item -> ti_Data; break;
         case FA_Text_HCenter:      LOD -> nFlags   = item -> ti_Data ? (LOD -> nFlags | FF_Text_HCenter) : (LOD -> nFlags - (LOD -> nFlags & FF_Text_HCenter)); break;
         case FA_Text_VCenter:      LOD -> nFlags   = item -> ti_Data ? (LOD -> nFlags | FF_Text_VCenter) : (LOD -> nFlags - (LOD -> nFlags & FF_Text_VCenter)); break;
         case FA_Text_Static:       LOD -> nFlags   = item -> ti_Data ? (LOD -> nFlags | FF_Text_Static)  : (LOD -> nFlags - (LOD -> nFlags & FF_Text_Static));  break;
      }
   }
   return NULL;
}
//+
///Text_Get
ULONG SAVEDS Text_Get(struct LocalObjectData *LOD,struct TagItem *Tags)
{
   struct TagItem *item;
   ULONG  *save;

   while (item = NextTagItem(&Tags))
   {
      save = (ULONG *)item -> ti_Data;

      switch (item -> ti_Tag)
      {
         case FA_Text:             *save = (ULONG)LOD -> pcText;    break;
         case FA_Text_PreParse:    *save = (ULONG)LOD -> pcPrep[0]; break;
         case FA_Text_AltPreParse: *save = (ULONG)LOD -> pcPrep[1]; break;
         case FA_Text_HCenter:     *save = (ULONG)(FALSE != (FF_Text_HCenter & LOD -> nFlags)); break;
         case FA_Text_VCenter:     *save = (ULONG)(FALSE != (FF_Text_VCenter & LOD -> nFlags)); break;
         case FA_Text_Static:      *save = (ULONG)(FALSE != (FF_Text_Static  & LOD -> nFlags)); break;
      }
   }
   return NULL;
}
//+
///Text_AskMinMax
ULONG SAVEDS Text_AskMinMax(struct FeelinClass *Class,APTR Obj,struct LocalObjectData *LOD)
{
   struct FeelinTextDisplay *td = LOD -> TextDisplay;

   if (LOD -> pcText)
   {
      F_Set(td,FA_TextDisplay_Font,(ULONG)_font(Obj));

      if (FF_Text_SetMin & LOD -> nFlags)
      {
         _minw(Obj) += td -> nWidth;
      }
      _minh(Obj) += td -> nHeight;
   }
   else
   {
      _minh(Obj) += _font(Obj) -> tf_YSize;
   }

   return F_SuperDoA(Class,Obj,FM_AskMinMax,NULL);
}
//+
///Text_Draw
ULONG SAVEDS Text_Draw(struct FeelinClass *Class,APTR Obj,struct LocalObjectData *LOD,ULONG *Args)
{
   struct FeelinTextDisplay     *td = LOD -> TextDisplay;
   struct FeelinRect             rect;
   STRPTR prep;
   ULONG  h;

   F_SuperDoA(Class,Obj,FM_Draw,Args); 

   rect.x1 = _mx(Obj) ; rect.x2 = rect.x1 + _mw(Obj) - 1;
   rect.y1 = _my(Obj) ; rect.y2 = rect.y1 + _mh(Obj) - 1;

   if (FF_Draw_Update & ((struct FS_Draw *)Args) -> Flags)
   {
      F_DrawBackground(Obj,rect.x1,rect.y1,rect.x2,rect.y2,NULL);
   }

   prep = LOD -> pcPrep[F_Get(Obj,FA_Selected) ? 1 : 0];
   if (prep == NULL) prep = LOD -> pcPrep[0];

   F_Set(td,FA_TextDisplay_PreParse,(ULONG)prep);

   if (FF_Text_VCenter & LOD -> nFlags)
   {
      h = rect.y2 - rect.y1 + 1;

      if (td -> nHeight < h)
      {
         rect.y1 = (h - td -> nHeight) / 2 + rect.y1;
      }
   }

   F_Do(td,FM_TextDisplay_Draw,&rect,_render(Obj));

   return NULL;
}
//+

///FCC_Dispatcher
ULONG ASM SAVEDS FCC_Dispatcher(REG(a2) struct FeelinClass *Class,REG(a0) APTR Obj, REG(d0) ULONG Method,REG(a1) ULONG *Args)
{
   struct LocalObjectData *LOD = INST_DATA(Class,Obj);

   switch (Method)
   {
      case FM_New:      return   Text_New       (Class,Obj,LOD,(struct TagItem *)Args);
      case FM_Dispose:           Text_Dispose   (Class,Obj,LOD,Args);
                        return   NULL;
      case FM_Set:               Text_Set(Obj,LOD,(struct TagItem *)Args);
                                 F_SuperDoA(Class,Obj,FM_Set,Args);
                        return   NULL;
      case FM_Get:               F_SuperDoA(Class,Obj,FM_Get,Args);
                                 Text_Get(LOD,(struct TagItem *)Args);
                        return   NULL;

      case FM_Setup:
         if (F_SuperDoA(Class,Obj,FM_Setup,Args))
         {
            F_Set(LOD -> TextDisplay,FA_TextDisplay_Font,(ULONG)_font(Obj));
            F_Do(LOD -> TextDisplay,FM_TextDisplay_Size,NULL);

            return TRUE;
         }
         else
         {
            return FALSE;
         }
      case FM_Cleanup:
         F_Set(LOD -> TextDisplay,FA_TextDisplay_Font,NULL);
         return F_SuperDoA(Class,Obj,FM_Cleanup,Args);

      case FM_AskMinMax:   return   Text_AskMinMax(Class,Obj,LOD);
      case FM_Draw:        return   Text_Draw     (Class,Obj,LOD,Args);
      default:             return   F_SuperDoA    (Class,Obj,Method,Args);
   }
}
//+
///FCC_Info
ULONG * ASM SAVEDS FCC_Info(REG(a0) struct FeelinBase *Feelin)
{
   static ULONG Tags[] =
   {
      FA_SuperID,    (ULONG) FC_Area,
      FA_DataSize,   sizeof (struct LocalObjectData),
      FA_Dispatcher, (ULONG) FCC_Dispatcher,
      NULL
   };

   FeelinBase  = Feelin;
   DOSBase     = Feelin->Dos;
   UtilityBase = Feelin->Utility;

   return Tags;
}
//+
