//=======================================================================
//@V@:Note: This file generated by vgen V1.00 (12:04:59 PM 23 Sep 1996).
//	vedcmdw.cpp:	Source for vedCmdWindow class
//=======================================================================

#include <v/vnotice.h>	// for vNoticeDialog
#include <v/vkeys.h>	// to map keys
#include <v/vfilesel.h>
#include <v/vfontsel.h>
#include <v/vutil.h>
#include <v/vynreply.h>
#include <v/vicon.h>

#include "vedapp.h"
#include "vseeci.h"	// command interp
#include "vedcmdw.h"	// our header
#include "vedcnv.h"     // canvas


//	Start defines for the main window with 100

//@V@:BeginIDs
    enum {
	m_FirstCmd = 100, 		// Dummy Command
	m_Options,			// set options
        m_View,				// view a file R/O
        m_EditHelp,
	lblLineCol,			// Status Bar
	lblIns,
	lblSBlank,
	lblMsg,
	blkLast				// Last item
      };
//@V@:EndIDs

//@V@:BeginPulldownMenu FileMenu
    static vMenu FileMenu[] =
      {
	{"&New", M_New, isSens, notChk, noKeyLbl, noKey, noSub},
	{"&Open...", M_Open, isSens, notChk, noKeyLbl, noKey, noSub},
        {"&View...", m_View, isSens, notChk, noKeyLbl, noKey, noSub},
	{"&Save", M_Save, isSens, notChk, noKeyLbl, noKey, noSub},
	{"Save &as...", M_SaveAs, isSens, notChk, noKeyLbl, noKey, noSub},
	{"&Close", M_CloseFile, isSens, notChk, noKeyLbl, noKey, noSub},
        {"Save and Close", M_SaveClose, isSens, notChk, noKeyLbl, noKey, noSub},
	{"-", M_Line, notSens, notChk, noKeyLbl, noKey, noSub},
	{"E&xit", M_Exit, isSens, notChk, noKeyLbl, noKey, noSub},
	{NULL}
      };
//@V@:EndPulldownMenu
    static vMenu EditMore[] =
      {
	{"Delete Line", edLineDelete, isSens,notChk,"^K",noKey,noSub},
        {"Delete To Front of Line", edLineDeleteFront, isSens,notChk,"^ABkSp",noKey,noSub},
	{"Delete To End of Line", edLineDeleteToEnd, isSens,notChk,"^ADel",noKey,noSub},
	{"Fold case", edCharFoldCase, isSens,notChk,"Shift-^C",noKey,noSub},
	{"Goto line", edLineGoto, isSens,notChk,"^G",noKey,noSub},
	{"Ins Char Value", edCharInsert, isSens,notChk,"^AIns",noKey,noSub},
	{"Open blank line", edLineOpen, isSens,notChk,"^O",noKey,noSub},
	{"Repaint screen", edVerify, isSens,notChk,"^Av",noKey,noSub},
        {NULL}
      };

//@V@:BeginPulldownMenu EditMenu
    static vMenu EditMenu[] =
      {
	{"Cut  ", M_Cut, notSens, notChk, "^X", noKey, noSub},
	{"Copy ", M_Copy, notSens, notChk, "^C", noKey, noSub},
	{"Paste", M_Paste, notSens, notChk, "^V", noKey, noSub},
	{"-", M_Line, notSens, notChk, noKeyLbl, noKey, noSub},
	{"Find", edFind, isSens,notChk,noKeyLbl,noKey,noSub},
	{"Find Next", edFindNext, isSens,notChk,noKeyLbl,noKey,noSub},
	{"Find Matching Paren", edBalMatch, isSens,notChk,noKeyLbl,noKey,noSub},
	{"-", M_Line, notSens, notChk, noKeyLbl, noKey, noSub},
        {"Edit Help", m_EditHelp, isSens, notChk, noKeyLbl, noKey, noSub},

	{NULL}
      };
//@V@:EndPulldownMenu

//@V@:BeginPulldownMenu OptMenu
    static vMenu OptMenu[] =
      {
	{"Font", M_Font,isSens,notChk,noKeyLbl,noKey,noSub},
	{NULL}
      };
//@V@:EndPulldownMenu

//@V@:BeginMenu StandardMenu
    static vMenu StandardMenu[] =
      {
	{"&File", M_File, isSens, notUsed, notUsed, noKey, &FileMenu[0]},
	{"&Edit", M_Edit, isSens, notUsed, notUsed, noKey, &EditMenu[0]},
	{"&Options", m_Options, isSens, notUsed, notUsed, noKey, &OptMenu[0]},
	{NULL}
      };
//@V@:EndMenu

//vbm1
#define open_width 16
#define open_height 16
static unsigned char open_bits[] = {
 0x00,0x00,0x00,0x0e,0x00,0x51,0x00,0x60,0x00,0x70,0x1c,0x00,0xe2,0x07,0x02,
 0x04,0x02,0x04,0xc2,0x7f,0xa2,0x2a,0x52,0x15,0xaa,0x0a,0x56,0x05,0xfc,0x03,
 0x00,0x00};
    static vIcon openI(&open_bits[0],open_height,open_width);

//vbm1
#define find_width 16
#define find_height 16
static unsigned char find_bits[] = {
 0x00,0x00,0xf0,0x01,0x08,0x02,0x44,0x04,0xa2,0x08,0x12,0x09,0xf2,0x09,0x12,
 0x09,0x14,0x05,0x08,0x0e,0xf0,0x1d,0x00,0x38,0x00,0x70,0x00,0x60,0x00,0x00,
 0x00,0x00};
    static vIcon findI(&find_bits[0],find_height,find_width);

//vbm1
#define findagn_width 16
#define findagn_height 16
static unsigned char findagn_bits[] = {
 0x00,0x00,0xf0,0x01,0x08,0x02,0x44,0x04,0xa2,0x08,0x12,0x09,0xf2,0x09,0x12,
 0x09,0x14,0x05,0x08,0x0e,0xf0,0x1d,0x66,0x38,0xcc,0x70,0x98,0x61,0xcc,0x00,
 0x66,0x00};
    static vIcon findagnI(&findagn_bits[0],findagn_height,findagn_width);

//@V@:BeginCmdPane ToolBar
    static CommandObject ToolBar[] =
      {
	{C_IconButton,M_Open,0,"Open",&openI,CA_None,isSens,NoFrame,0,0,0,"Open File"},
	{C_Blank,99,0," ",NoList,CA_None,isSens,NoFrame,0,0},
	{C_IconButton,edFind,0,"Find",&findI,CA_None,isSens,NoFrame,0,0,0,"Find"},
	{C_IconButton,edFindNext,0,"Find Next",&findagnI,CA_None,isSens,NoFrame,0,0,0,"Find Next"},
	{C_EndOfList,0,0,0,0,CA_None,0,0,0}
      };
//@V@:EndCmdPane

//@V@:BeginStatPane StatBar
    static vStatus StatBar[] =
      {
	{"1/1      ", lblLineCol, CA_None, isSens, 0},
	{"   Insert   ", lblIns, CA_None, isSens, 0},
	{" ", lblSBlank, CA_NoBorder, isSens, 0},
	// handle messages up to 40 chars
	{"                                        ", lblMsg, CA_NoBorder, isSens, 0},
	{0,0,0,0,0}
      };
//@V@:EndStatPane


    static int filterIndex = 0;
    static char* filter[] =
      {
        "*",
        "*.txt",
        "*.c;*.cpp;*.cxx;*.h",
        0
      };


//====================>>> vedCmdWindow::vedCmdWindow <<<====================
  vedCmdWindow::vedCmdWindow(char* name, int width, int height) :
    vCmdWindow(name, width, height)
  {
    UserDebug1(Constructor,"vedCmdWindow::vedCmdWindow(%s) Constructor\n",name)

    // local inits

    fileName[0] = 0;

    // The Menu Bar
    vedMenu = new vMenuPane(StandardMenu);
    AddPane(vedMenu);

    // The Command Pane
    vedCmdPane = new vCommandPane(ToolBar);
    AddPane(vedCmdPane);

    // The Canvas
    vedCanvas = new vedTextEditor((VCmdWindow*)this);
    AddPane(vedCanvas);

    if (((vedApp*)theApp)->GetEmulation() == See)
      {
        vedCI = (vTextEdCmdInterp*) new vSeeCI(vedCanvas, this); // override interp
    					// ed canvas will do delete at end
        vedCanvas->ChangeCmdInterp(vedCI);
      }
    else
	vedCI = 0;

    // The Status Bar
    vedStatus = new vStatusPane(StatBar);
    AddPane(vedStatus);

    // Associated dialogs


    // Show Window

    ShowWindow();
    vedCanvas->ShowVScroll(1);
#ifdef V_VersionX
    vedFont.SetFontValues(vfFixed,12);	// use Courier rathern than default
#else
#ifdef DEVEL
    vedFont.SetFontValues(vfFixed,10,vfNormal,vfBold);	// use Courier rathern than default
#else
    vedFont.SetFontValues(vfFixed,10);	// use Courier rathern than default
#endif
#endif
    vedCanvas->SetFont(vedFont);
    vedCanvas->SetTextRowsCols(24,80);
    (vedCanvas->GetCmdInterp())->InitCmdInterp();

  }

//====================>>> vedCmdWindow::~vedCmdWindow <<<====================
  vedCmdWindow::~vedCmdWindow()
  {
    UserDebug(Destructor,"vedCmdWindow::~vedCmdWindow() destructor\n")

    // Now put a delete for each new in the constructor.

    delete vedMenu;
    delete vedCanvas;
    delete vedCmdPane;
    delete vedStatus;
  }

//====================>>> vedCmdWindow::ChangeLoc <<<====================
  void vedCmdWindow::ChangeLoc(long line, int col)
  {
    char buff[20];
    char colbuff[10];
    char outbuff[20];
    int ll;

    LongToStr(line,buff);

    IntToStr(col,colbuff);

    // center the line/col string

    int totalLen = strlen(buff) + strlen(colbuff) + 1;

    int add = (9 - totalLen) / 2;

    for (ll = 0 ; ll < add ; ++ll)
	outbuff[ll] = ' ';
    outbuff[ll] = 0;

    strcat(outbuff,buff); strcat(outbuff,"/");
    strcat(outbuff,colbuff);

    // pad with trailing blanks so X doesn't shift things

    for (ll = strlen(outbuff) ; ll < 9 ; ++ll)
	outbuff[ll] = ' ';
    outbuff[ll] = 0;
    SetString(lblLineCol,outbuff);

  }

//====================>>> vedCmdWindow::ChangeInsMode <<<====================
  void vedCmdWindow::ChangeInsMode(int IsInsMode, char* msg)
  {
    if (msg != 0 && *msg != 0)
        SetString(lblIns,msg);
    else if ((vedCanvas->GetEdState()).readOnly)
        SetString(lblIns,"  View  ");
    else if (IsInsMode)
	SetString(lblIns," Insert ");
    else
	SetString(lblIns,"Overtype");
  }

//====================>>> vedCmdWindow::StatusMessage <<<====================
  void vedCmdWindow::StatusMessage(char *msg)
  {
    char lineout[42];
    int ix;

    // copy up to 40 chars
    for (ix = 0 ; ix < 40 && msg[ix] ; ++ix)
	lineout[ix] = msg[ix];

    // pad with trailing blanks
    for ( ; ix < 40 ; ++ix)
	lineout[ix] = ' ';

    lineout[ix] = 0;

    SetString(lblMsg,lineout);
  }

//====================>>> vedCmdWindow::ErrorMsg <<<====================
  void vedCmdWindow::ErrorMsg(char *str)
  {
      StatusMessage(str);
  }

//====================>>> vedCmdWindow::KeyIn <<<====================
  void vedCmdWindow::KeyIn(vKey keysym, unsigned int shift)
  {
    StatusMessage(" ");
    if (!vedCanvas->EditKeyIn(keysym, shift))
	vCmdWindow::KeyIn(keysym, shift);
  }

//==============>>> vedCmdWindow::CheckClose <<<================
  int vedCmdWindow::CheckClose(int ask)
  {
    // Checks to see if the user wants to save changes, if changes have been
    // done, before it closes the application.
    // Return 1 if ok to close now, 0 to abort

    if (vedCanvas->Changed())    // changes have been made
      {
	if (ask)
	  {
	    vYNReplyDialog ynr(this);
	    int ans = ynr.AskYN("Save new or changed file?");
	    if (ans == 0)
	      {
		return 1;           // don't want to save
	      }
	    if (ans == -1)          // cancel
		return 0;
	  }
 
        // ok, want to save changed file
        if (*fileName)                    // have a name
          {
            if (!vedCanvas->SaveFile(fileName))        // Save in fileName
              {
                vNoticeDialog note(this);       // for user notification
                note.Notice("Unable to save file");
                return 0;
              }
          }
        else                            // need to request name
          {
            vFileSelect fsel(this);     // V file select dialog
 
            if (!fsel.FileSelectSave("Save file as",
                fileName,99,filter,filterIndex) || !*fileName)
            return 0;
 
            if (!vedCanvas->SaveFile(fileName))        // Save in fileName
              {
                vNoticeDialog note(this);       // for user notification
                note.Notice("Unable to save file");
                return 0;
              }
          }
      }
    return 1;
  }
 
//====================>>> vedCmdWindow::WindowCommand <<<====================
  void vedCmdWindow::WindowCommand(ItemVal id, ItemVal val, CmdType cType)
  {
    // Default: route menu and toolbar commands here

    UserDebug1(CmdEvents,"vedCmdWindow:WindowCommand(%d)\n",id)


    StatusMessage(" ");
    switch (id)
      {
	//@V@:Case M_New
	case M_New:
	  {
            vedCmdWindow* ncmdw;;
            ncmdw = (vedCmdWindow*) theApp->NewAppWin(0,"V Text Editor", 100, 50);
            if (ncmdw)		// If a new window, raise it
              {
                ncmdw->RaiseWindow();
              }
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_Open
        case m_View:
	case M_Open:
	  {
	    char name[100] = ""; // start out with null name
	    vFileSelect fsel(this);     // make an instance

	    int oans = fsel.FileSelect("Open file",name,99,filter,filterIndex);

	    if (oans)
	      {
		vedCmdWindow* cmdw = this;
		if (*fileName != 0 || vedCanvas->Changed()) // already have file open
		  {
		    cmdw = (vedCmdWindow*) theApp->NewAppWin(0,"V Text Editor", 100, 50);
		    if (!cmdw)
			break;
                  }
		if (!cmdw->OpenFile(name,(id == m_View)) )
		  {
		    vNoticeDialog note(this);
		    note.Notice("Unable to open specified file.");
		    if (cmdw != this)		// A new window?
			delete cmdw;
                    break;
		  }
		else
		  {
		    if (cmdw != this)		// If a new window, raise it
			cmdw->RaiseWindow();
		  }
	      }

	    break;
	  }	//@V@:EndCase

	//@V@:Case M_Save
	case M_Save:
	  {
	    CheckClose(0);
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_SaveAs
	case M_SaveAs:
	  {
            vFileSelect fsel(this);     // V file select dialog
 
            if (!fsel.FileSelectSave("Save file as",
                fileName,99,filter,filterIndex) || !*fileName)
	        break;
 
            if (!vedCanvas->SaveFile(fileName))        // Save in fileName
              {
                vNoticeDialog note(this);       // for user notification
                note.Notice("Unable to save file");
              }
	    else
		SetTitle(fileName);
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_CloseFile
	case M_CloseFile:
	  {
	    if (!CheckClose())
		break;
	    *fileName = 0;			// no file now
	    CloseWin();
	    break;
	  }	//@V@:EndCase

	//@V@:Case m_SaveClose
	case M_SaveClose:
	  {
	    if (!CheckClose(0))
		break;
	    CloseWin();
	    break;
	  }	//@V@:EndCase


	//@V@:Case M_Exit
	case M_Exit:
	  {
	    theApp->Exit();
	    break;
	  }	//@V@:EndCase


	//@V@:Case M_Font
	case M_Font:
	  {
	    vFontSelect fd(this);

	    (void) fd.FontSelect(vedFont);
	    vedCanvas->SetFont(vedFont);
	    break;
	  }	//@V@:EndCase


	//@V@:Case M_Cut
	case M_Cut:
	  {
	    vedCanvas->EditCommand(edCut,0);
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_Copy
	case M_Copy:
	  {
	    vedCanvas->EditCommand(edCopy,0);
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_Paste
	case M_Paste:
	  {
	    vedCanvas->EditCommand(edPaste,0);
	    break;
	  }	//@V@:EndCase

	//@V@:Case M_SetEmulation
	case M_SetEmulation:
	  {
	    if ((Emulation) val == See)
	      {
		vedCI = (vTextEdCmdInterp*) new vSeeCI(vedCanvas, this); // override interp
		// ed canvas will do delete at end
	      }
	    else
		vedCI = 0;

	    vedCanvas->ChangeCmdInterp(vedCI);
	    (vedCanvas->GetCmdInterp())->InitCmdInterp();
	  }

	default:	// route unhandled commands through editor
	  {
	    if (vedCanvas->EditCommand(id, 1) < 0)
		vCmdWindow::WindowCommand(id, val, cType);
	    break;
	  }
      }
  }

//====================>>> vedCmdWindow::OpenFile <<<====================
  int vedCmdWindow::OpenFile(char* name, int ReadOnly)
  {
    if (!name || !*name)
	return 0;

    if (!vedCanvas->ReadFile(name,1))
      {
	vNoticeDialog note(this);       // for user notification
	note.Notice("Unable to open specified file");
	return 0;
      }
    SetTitle(name);
    strcpy(fileName,name);

    char* CExts[] = {".cpp", ".CPP", ".C", ".c", ".cxx", ".CXX",
               ".h", ".H", ".hpp", ".HPP", ""};

    edState curState = vedCanvas->GetEdState();
    curState.readOnly = ReadOnly;
    curState.ftype = Text;			// assume Text
    for (int ix = 0 ; *CExts[ix] ; ++ix)	// check C extensions
      {
        if (strstr(name,CExts[ix]) != 0)	// found one!
          {
            curState.ftype = CPP;
            break;
          }
      }

    vedCanvas->SetEdState(curState);
    vedCanvas->Verify();
    
    // ChangeInsMode(1);

    return 1;
  }
