//===============================================================
// vtextc.cxx   - Text output cmd - Windows
//
// Copyright (C) 1995,1996,1997,1998  Bruce E. Wampler
//
// This file is part of the V C++ GUI Framework, and is covered
// under the terms of the GNU Library General Public License,
// Version 2. This library has NO WARRANTY. See the source file
// vapp.cxx for more complete information about license terms.
//===============================================================
#include <v/vos2.h>     // for OS/2 stuff
#include <v/vapp.h>
#include <v/vtextc.h>   // our definitions
#include <v/vcmdprnt.h> // a command parent
#include <v/vutil.h>

  // Text boxes are subclassed to this procedure
  MRESULT EXPENTRY TextProc(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
  // this is a pointer to the original MLE procedure that is subclassed
  PFNWP orgTextProc;


//=====================>>> vTextCmd::vTextCmd <<<=======================
  vTextCmd::vTextCmd(vCmdParent* dp, CommandObject* dc) :
            vCmd(dp, dc)
  {
    initialize();
  }
//=====================>>> vTextCmd::~vTextCmd <<<=======================
  vTextCmd::~vTextCmd()
  {
    SysDebug(Destructor,"vTextCmd::~vTextCmd() destructor\n")
  }
//=====================>>> vTextCmd::initialize <<<=======================
  void vTextCmd::initialize(void)
  {
    // multiline, boxed text output
    SysDebug(Constructor,"vTextCmd::vTextCmd() constructor\n")
    int numLines;
    char* useText;
    char* winCopy = 0;
    char* theText;
    long style = MLS_READONLY;

    CopyToLocal();                      // Make local copies of CmdObject

    if (!_itemList || (*(char*)_itemList == 0))
	theText = (char*) _title;
    else
	theText = (char*)_itemList;

    if (!(dlgCmd->attrs & CA_NoBorder))
	style |= MLS_BORDER;

    if (!(dlgCmd->attrs & CA_Hidden))   // Check for Hidden
	style |= WS_VISIBLE;
    // vTextLen returns the max number of characters per line and the number of lines
    _w = vTextLen(theText, numLines)*5+4; // set my width AND get numLines

    // calculate max width of multiline text string
    char *str, *start, word[1024];
    int width, maxW=0;
    str=theText;
    start=theText;
    for (int ix=0; *str; str++)
    {
      if (*str == '\n')    // end of current line
      {
        strncpy(word, start, ix);
        width = LabelWidth(word);  // width of current word
        if (width > maxW)
          maxW = width;
        ix = 0;  // reset posn counter
        start = str+1;
      }
      else
        ix++;
    }
    strcpy(word, start);
    width = LabelWidth(word);  // width of current word
    if (width > maxW)
      maxW = width;

    _w = maxW + 8; // set my width

    if (dlgCmd->size > 0)               // may reset title!
    {
      _w = dlgCmd->size;
    }

    if (_parentWin->paneType() == P_Status)
    {
      _h = (LabelHeight() * numLines) + 4;       // (was 7 * numLines)
    }
    else
    {
      _h = (LabelHeight() * numLines) + 4;       // (was 7 * numLines)
    }
    useText = theText;

    if (numLines > 1)           // have to convert \n to \r\n
    {
      winCopy = new char[(strlen(theText) + numLines + 1)];
      char * cp;
      for (cp = winCopy ; *useText ; )
      {
	if (*useText == '\n')       // add extra \r
	  *cp++ = '\r';
	*cp++ = *useText++;
      }
      *cp = 0;                        // terminate string
      useText = winCopy;
    }

    // set the entryfield colors so they blend into the dialog background
    _PPColor[0].PPtype = PP_BACKGROUNDCOLORINDEX;
    _PPColor[0].PPval.color = SYSCLR_DIALOGBACKGROUND;
    _PPColor[1].PPtype = PP_DISABLEDBACKGROUNDCOLORINDEX;
    _PPColor[1].PPval.color = SYSCLR_DIALOGBACKGROUND;
    _PPColor[2].PPtype = PP_HILITEBACKGROUNDCOLORINDEX;
    _PPColor[2].PPval.color = SYSCLR_DIALOGBACKGROUND;
    _PPColor[3].PPtype = PP_HILITEFOREGROUNDCOLORINDEX;
    _PPColor[3].PPval.color = SYSCLR_MENUTEXT;
    _PPColor[4].PPtype = 0;    // end of array marker

    _parentWin->SetPosition(_x, _y, _w, _h, dlgCmd->cFrame, dlgCmd->cRightOf,
	dlgCmd->cBelow);

      // inc y positions control lower in the allocate ddialog space
      // dec h makes control smaller in allocated space
      _y += 1;
//      _h -= 1;   // we play this game to get better positioning in a frame

    _CtrlOffset = _parentWin->AddDlgControl(_x, _y , _w, _h, _cmdId,
	   style, WC_MLE, useText, _parentWin->AssyPresParams(_PPColor), 0, NULL);

    if (winCopy != 0)
	delete [] winCopy;
  }
//================>>> vTextCmd::SetCmdVal <<<============================
  void vTextCmd::SetCmdVal(ItemVal val, ItemSetType st)
  {
    SysDebug1(Misc,"vTextCmd::SetCmdVal(val:%d)\n",val)
    HWND myHwnd = GetMyHwnd(_cmdId);

    switch (st)
    {
      case Sensitive:
	_Sensitive = val;               // set
	WinEnableWindow (myHwnd, val);
	break;

      case Hidden:
	if (val)
	  WinShowWindow (myHwnd, FALSE);
	else
	  WinShowWindow (myHwnd, TRUE);
	break;
    }
  }
//================>>> vTextCmd::SetCmdStr <<<============================
  void vTextCmd::SetCmdStr(VCONST char* str)
  {
    char trunc[80];
    SysDebug1(Misc,"vTextCmd::SetCmdStr(str:%s)\n",strncpy(trunc, str, 60) )
    int numLines;
    VCONST char* useText = str;
    char* winCopy = 0;
    HWND myHwnd = GetMyHwnd(_cmdId);

    (void) vTextLen(str, numLines);
    if (numLines > 1)           // have to convert \n to \r\n
      {
	winCopy = new char[(strlen(str) + numLines + 1)];
	char * cp;
	for (cp = winCopy ; *useText ; )
	  {
	    if (*useText == '\n')       // add extra \r
		*cp++ = '\r';
	    *cp++ = *useText++;
	  }
	*cp = 0;                        // terminate string
	useText = winCopy;
      }
    WinSetWindowText(myHwnd, useText);

    if (winCopy != 0)
	delete [] winCopy;
    _title = str;
  }

//================>>> vTextCmd::SubClass <<<============================
  int vTextCmd::DRAWITEM(int id, OWNERITEM* hwnd)
  {
    // used to subclass text labels during the WM_INITDLG setup
    HWND hControl = GetMyHwnd(id);
    WinSetWindowULong(hControl, QWL_USER, (LONG) this);
    _orgTextProc = WinSubclassWindow(hControl, TextProc);
    SysDebug2(OS2Dev,"vTextCmd::SubClass this:%x hControl:%x \n", this, hControl)
    return (0);
  }

//====================>>> TextProc <<<=======================
// we subclass the C_BoxedLabel so we can intercept any attempt
// to activate it with a mouse click
  MRESULT EXPENTRY TextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  {
    vTextCmd* thisCmd = (vTextCmd*) WinQueryWindowULong( hwnd, QWL_USER ); // Pointer from window word
    if (!thisCmd)
    {
      return (MRESULT) WinDefDlgProc(hwnd, msg, mp1, mp2);
    }
    else
      return (MRESULT) thisCmd->vTextProc(hwnd, msg, mp1, mp2);
  }



//====================>>> vTextProc <<<=======================
  MRESULT vTextCmd::vTextProc(HWND hBtn, ULONG uMsg, MPARAM mp1, MPARAM mp2)
  {
    // set the original frame procedure
    orgTextProc = (PFNWP) _orgTextProc;

    switch (uMsg)
    {
      case WM_CHORD:
      case WM_BUTTON1DBLCLK:
      case WM_BUTTON2DBLCLK:
      case WM_BUTTON3DBLCLK:
      case WM_BUTTON1DOWN:
      case WM_BUTTON2DOWN:
      case WM_BUTTON3DOWN:
      case WM_SETFOCUS:
      {
        // user has clicked on the label, so trap message and prevent
        // it from reaching the entry field procedure so that control
        // does not get focus
        return 0;
      }
    }
    return orgTextProc(hBtn, uMsg, mp1, mp2);
  }

