/*****************************************************************************/
/* IBM Internal Use Only                                                     */
/* Copyright (c) IBM Corp 19XX                                               */
/*---------------------------------------------------------------------------*/
/* File        : pmBandit.cpp                                                */
/* Description : Implements the                                              */
/*                                                                           */
/*---------------------------------------------------------------------------*/
/* History                                                                   */
/*---------------------------------------------------------------------------*/
/* Date        | Event                                   | Person            */
/*---------------------------------------------------------------------------*/
/* 1997-06-11  | Created                                 | FB                */
/* 1997-06-12  | Finallizied the CommandHandler          | FB                */
/* 1997-11-07  | Made Win32 comp.                        | FB                */
/*****************************************************************************/

#include "..\..\BanditTagger\PM_Interface\pmBandit.hpp"
#include "..\..\BanditTagger\PM_Interface\pmBandit.rch"
#include "..\..\BanditTagger\Tagger\tagini.hpp"
#include "..\..\BanditTagger\Tagger\commonDef.hpp"
#include <IThread.hpp>
#include <ITrace.hpp>
#include <IFont.hpp>
#include <ITitle.hpp>
#include <IPoint.hpp>
#include <IWindow.hpp>
#include <ISysmenu.hpp>
#include <fstream.h>
#include <stdlib.h>

const unsigned long IDL_TAGLINE_PAGE(100);

//***************************************************************************
// TAGNotebookPage::TAGNotebookPage
// Input parameters : IWindow* IString
// The member constructs a IFrameWindow with a listbox client. Then starts
// a thread.
// Returncodes :
//***************************************************************************

TAGNotebookPage::TAGNotebookPage(IWindow* pParentOwner, IString filename, Boolean disable)
: IFrameWindow(IDL_TAGLINE_PAGE, pParentOwner, pParentOwner, IRectangle(), IWindow::visible)
, _filename(filename)
, _listbox(IC_FRAME_CLIENT_ID, this, this)
{
  this->setClient(&_listbox);
  this->setAutoDeleteObject();

  _disable = disable;
  if (_disable)
    _listbox.enable(false);

  IThread()
    .setStackSize(0x1000)
    .start(new IThreadMemberFn<TAGNotebookPage>(*this, loadTagFile));

}

//***************************************************************************
// TAGNotebookPage::loadTagFile
// Input parameters :
// The member function loads a file, and insert the lines into a listbox.
// Returncodes : void
//***************************************************************************

void TAGNotebookPage::loadTagFile()
{
  ifstream      in    (_filename);
  Boolean       first (true);
  Boolean       newTag(true);
  unsigned long index (0);

  if (in.good()) {
    IString tagline;
    for (tagline = IString::lineFrom(in);
         in.good() || tagline != IString();
         tagline = IString::lineFrom(in))
    {
      if (!first) {
        index = _listbox.addAsLast(tagline);
        // The two next linies only have meaning for wysiwyg, but are always inserted.
        if (newTag) {
          _listbox.setItemHandle(index, 1);
          newTag = false;
        }
        if (tagline == IString())
          newTag = true;
      } else first = false;

    }
  }
  if (_disable) {
    // ** Notice insert line 2 first.
    _listbox.addAsFirst(IString());
    _listbox.addAsFirst(TXT_LISTBOX_NOT_REG);
  }
}

//***************************************************************************
// TAGNotebook::TAGNotebookSelect::enter
// Input parameters : IControlEvent& ctrlEvt
// The member saves the last selected listbox.
// Returncodes : Boolean.
//***************************************************************************

Boolean TAGNotebook::TAGNotebookSelect::enter(IControlEvent& ctrlEvt)
{
  IFUNCTRACE_DEVELOP();
  _notebook->handleOk();
  ITRACE_DEVELOP(IString("enter - Listbox line no.: ") + _notebook->itemText());
  return false;
}

//***************************************************************************
// TAGNotebookSelect& handleEventsFor
// Input parameters : IListBox*
// The
// Returncodes : TAGNotebookSelect&
//***************************************************************************

TAGNotebook::TAGNotebookSelect&
  TAGNotebook::TAGNotebookSelect::handleEventsFor(IListBox* aListBox)
{
  ISelectHandler::handleEventsFor(aListBox);
  return *this;
}

//***************************************************************************
// TAGNotebook::mouseClicked
// Input parameters : IMouseClickEvent
// The queries the selected text.
// Returncodes : Boolean.
//***************************************************************************

Boolean TAGNotebook::mouseClicked(IMouseClickEvent &mouseClick)
{
  const IListBox* listbox = (IListBox*) mouseClick.controlWindow();

  if (listbox->selection() != IListBox::notFound) {
    if (_userIni.wysiwyg()) {
      _itemText = IString();  // Have to reset the string
      unsigned long index(listbox->selection());
      while (listbox->itemHandle(index) == 0 && listbox->itemText(index) != IString())
        index--;
      while (listbox->count() > index && listbox->itemText(index) != IString())
        _itemText += listbox->itemText(index++)+"\n";
      _itemText.stripTrailing("\n");
    } else
      _itemText = listbox->itemText(listbox->selection());
    _pInfoArea->setText(_itemText);
  }
  return false;
}


//***************************************************************************
// TAGNotebook::TAGNotebook
// Input parameters : MList<IString*>
// The constructs the TAGNotebook
// Returncodes : Boolean.
//***************************************************************************

TAGNotebook::TAGNotebook(MList<IString>& afilenameList, const IString& filepath,
                         TAGUserIni& aUserIni)
: IFrameWindow(WND_MAIN_BANDIT,
               IWindow::desktopWindow()                      ,
               0                                             ,
               IRectangle()                                  ,
               IFrameWindow::defaultStyle()                  |
               IFrameWindow::dialogBackground                |
               IFrameWindow::minimizedIcon                   |
               IFrameWindow::shellPosition                   )
, _filenameList(afilenameList)
, _filepath(filepath)
, _userIni(aUserIni)
, _selectHandler(this)
{}

//***************************************************************************
// TAGNotebook::command
// Input parameters : ICommandEvent& cmdEvt
// The command handler.
// Returncodes : Boolean.
//***************************************************************************

Boolean TAGNotebook::command(ICommandEvent& cmdEvt)
{
  Boolean processed(false);
  switch (cmdEvt.commandId()) {
  case DID_OK:
    this->handleOk();
    break;
  case DID_CANCEL:
    this->dismiss(DID_CANCEL);
    processed = true;
    break;
  } // endswitch
  return processed;
}

//***************************************************************************
// TAGNotebook::handleOk
// Input parameters :
// The member saves the selected line, and closes the notebook.
// Returncodes : Boolean.
//***************************************************************************

Boolean TAGNotebook::handleOk()
{
  _itemText.change(_userIni.newline(), "\n");
  this->dismiss(DID_OK);
  return true;
}

//***************************************************************************
// TAGNotebook::layout
// Input parameters :
// The inserts the insert the creation of the notebook & buttons.
// Returncodes : long
//***************************************************************************

long TAGNotebook::layout()
{
  this->setFont(IFont("Helv", 8));
  IMultiCellCanvas* clientCanvas = new IMultiCellCanvas(IC_FRAME_CLIENT_ID,
                                                        this, this);

  // Set the auto delete object;
  clientCanvas->setAutoDeleteObject();

  // Create the info area
  _pInfoArea = new IInfoArea(this);
  _pInfoArea->setInactiveText(WND_MAIN_BANDIT);

  // Add the windows to the multiCellCanvas.
  clientCanvas->addToCell(this->insertNotebookPages(clientCanvas), 1, 1);
  clientCanvas->addToCell(this->insertButtons(clientCanvas)      , 1, 2);
  clientCanvas->setColumnWidth(1, 1, true);
  clientCanvas->setRowHeight  (1, 1, true);
  this->setClient(clientCanvas);

  ICommandHandler::handleEventsFor(this);

  return 0;
}

//***************************************************************************
// TAGNotebook::insertNotebookPages
// Input parameters :
// The inserts the pages into the notebook.
// Returncodes : long
//***************************************************************************

INotebook* TAGNotebook::insertNotebookPages(IMultiCellCanvas *pParentOwner)
{
  INotebook*        notebook     = new INotebook(0x002,
                                                 pParentOwner,
                                                 pParentOwner,
                                                 IRectangle(),
                                                 INotebook::spiralBinding|
                                                 INotebook::polygonTabs|
                                                 INotebook::backPagesTopRight|
                                                 INotebook::tabTextCenter|
                                                 INotebook::majorTabsTop |
                                                 IWindow::visible);

  INotebook::PageSettings pageSettings(INotebook::PageSettings::autoPageSize |
                                       INotebook::PageSettings::majorTab     );

  // Set the auto delete object;
  notebook->setAutoDeleteObject();

  // Insert the pages.
  IString*           pfile(0);
  IFont                       notebookFont(notebook);
  IString                     filename;
  unsigned long               maxWidth(0);
  unsigned short              count(0);
  Boolean                     disable(false);

  for (pfile = _filenameList.getFirst();
       pfile;
       pfile = _filenameList.getNext())
  {
    filename = *pfile;
    if (filename != _userIni.manualTag()) {
      #ifndef __TOS_OS2__  // Only windows users
      count++;
      if (count > 2 && !_userIni.registered())
        disable = true;
      #endif
      TAGNotebookPage* notebookPage = new TAGNotebookPage(notebook, _filepath+filename, disable);

      pageSettings.setTabText(filename);
      maxWidth = (unsigned long) max(maxWidth, notebookFont.minTextWidth(filename));
      _selectHandler.handleEventsFor(notebookPage->listbox());
      IMouseHandler::handleEventsFor(notebookPage->listbox());
      notebook->addLastPage(pageSettings, notebookPage);
    }
  }
  // Adjust the notebook.
  notebook->setMajorTabSize(ISize(maxWidth+10, notebookFont.maxCharHeight()+10));

  return notebook;
}

//***************************************************************************
// TAGNotebook::insertButtons
// Input parameters : const IWindow*
// The inserts create the buttons multi cell canvas and inserts the buttons.
// Returncodes : IMultiCellCanvas
//***************************************************************************

IMultiCellCanvas* TAGNotebook::insertButtons(IMultiCellCanvas* pParentOwner)
{
  IMultiCellCanvas* buttonCanvas = new IMultiCellCanvas(0x001,
                                                        pParentOwner,
                                                        pParentOwner);
  buttonCanvas->setAutoDeleteObject();
  // The ok button.
  _ppbOk     = new IPushButton(DID_OK,
                               buttonCanvas,
                               buttonCanvas);
  _ppbOk->enableDefault();

  // Cancel button.
  _ppbCancel = new IPushButton(DID_CANCEL,
                               buttonCanvas,
                               buttonCanvas);

  // Set the button text.
  _ppbOk->setText    (_ppbOk->id());
  _ppbCancel->setText(_ppbCancel->id());
  // Group the buttons.
  _ppbOk->enableTabStop().enableGroup();

  // Add the buttons to the canvas.
  buttonCanvas->addToCell(_ppbOk    , 2, 2);
  buttonCanvas->addToCell(_ppbCancel, 4, 2);

  unsigned long buttonWidth = (unsigned long) max(_ppbOk->minimumSize().width(),
                                                  _ppbCancel->minimumSize().width());
  buttonCanvas->setColumnWidth(2, buttonWidth);
  buttonCanvas->setColumnWidth(4, buttonWidth);
  buttonCanvas->setColumnWidth(1, buttonWidth, true);
  buttonCanvas->setColumnWidth(5, buttonWidth, true);
  buttonCanvas->setRowHeight  (3, buttonCanvas->defaultCell().height());

  return buttonCanvas;
}

//***************************************************************************
// TAGViewer::TAGViewer
// Input parameters : MList<IString*>
// The constructs the viewer window
// Returncodes :
//***************************************************************************

TAGViewer::TAGViewer(MList<IString>& tagList, long aValue, const IString& newline)
: IFrameWindow(WND_INSERTED_TAGS,
               IWindow::desktopWindow()                      ,
               0                                             ,
               IRectangle()                                  ,
               IFrameWindow::dialogBackground                |
               IFrameWindow::dialogBorder                    |
               IFrameWindow::windowList                      |
               IFrameWindow::titleBar                        |
               IFrameWindow::shellPosition)
, _timer(aValue)
{
  this->setFont(IFont("Helv", 8));
  IMultiCellCanvas*  clientCanvas = new IMultiCellCanvas(IC_FRAME_CLIENT_ID,
                                                         this,
                                                         this);
  clientCanvas->setAutoDeleteObject();

  ITitle title(this);

  title.setTitleText(title.text() + (tagList.numOfItems()>1 ? "s :" :" :"));

  long             row(2);
  unsigned long    maxWidth(title.minimumSize().width());
  unsigned long    desktopWidth(IWindow::desktopWindow()->size().width());
  IPoint           point(this->position());

  IString* ptag(0);

  for (ptag = tagList.getFirst(); ptag; ptag = tagList.getNext()) {
    IString tagString(*ptag);
    short   pos(0);
    short   prePos(1);
    short   length(1);
    Boolean secondLine(false);
    do {
      pos++;  // Move the index one ahead.
      pos = tagString.indexOf(newline, pos);
      IStaticText *tag = new IStaticText(0x001,
                                         clientCanvas,
                                         clientCanvas);
      if (pos == 0)
        length  = tagString.size() - prePos+1;
      else
        length = pos - prePos;
      tag->setText(IString(secondLine ? "  " : "- ") + tagString.subString(prePos, length));
      tag->setAutoDeleteObject();
      maxWidth = (unsigned long) max(tag->minimumSize().width(), maxWidth);
      clientCanvas->addToCell(tag, 1, row++);
      prePos = pos;
      prePos += newline.size();
      secondLine =true;
    } while (pos);
  } // endfor
  clientCanvas->setColumnWidth(1, desktopWidth < maxWidth ? desktopWidth : maxWidth)
               .setRowHeight  (row, IMultiCellCanvas::defaultCell().height());

  if ((point.x()+maxWidth) > desktopWidth)
    point.setX(point.x()-(point.x()+maxWidth-desktopWidth));
  if (point.x() < 0) point.setX(0);

  this->setClient(clientCanvas);
  this->moveSizeToClient(IRectangle(point, clientCanvas->minimumSize()));
  IFrameHandler::handleEventsFor(this);
}

//***************************************************************************
// TAGViewer::activated
// Input parameters : IFrameEvent&
// The
// Returncodes :
//***************************************************************************

Boolean TAGViewer::activated(IFrameEvent& frameEvt)
{
  timer.start(new ITimerMemberFn0<TAGViewer>(*this, closeFrame), _timer);
  return false;
}

void TAGViewer::closeFrame()
{
  timer.stop();
  this->dismiss();
}
