/*****************************************************************************/
/* FA Partners - Created by Flemming Bregnvig bregnvig@usa.net               */
/* Copyright (c) FA Partners 1997, 1998                                      */
/*---------------------------------------------------------------------------*/
/* Name        : netscape.cpp                                                */
/* Description : Handles all the stuff related to netscape.                  */
/*                                                                           */
/*---------------------------------------------------------------------------*/
/* History                                                                   */
/*---------------------------------------------------------------------------*/
/* Date        | Event                                   | Person            */
/*---------------------------------------------------------------------------*/
/* 1998-01-28  | Created                                 | FB                */
/*****************************************************************************/

#include <iobjwin.hpp>
#include <iframe.hpp>
#include <ithread.hpp>
#include <iclipbrd.hpp>
#include <isysmenu.hpp>

#include <stdio.h>

#include "..\tagger\netscape.hpp"
#include "..\tagger\mailmain.hpp"
#include "..\PM_Interface\pmBandit.rch"

  // The procedures to be loaded from the Dll
PINITDLL            BANInitDLL;
PSTARTINPUTHOOK     BANStartInputHook;
PSTOPINPUTHOOK      BANStopInputHook;
PDESTROYDLL         BANDestroyDLL;

const char  HOOKDLL[]        = "hookdll.dll";
const char  INITDLL[]        = "InitDLL";
const char  STARTINPUTHOOK[] = "StartInputHook";
const char  STOPINPUTHOOK[]  = "StopInputHook";
const char  DESTROYDLL[]     = "DestroyDLL";
//***************************************************************************
// BANNetscape::start
// Input parameters :
// This member contructs the BANNetscape object.
// Returncodes :
//***************************************************************************

Boolean BANNetscape::start()
{
  Boolean rc(true);
  IFrameWindow::Style style((_userIni.windowList()
    ? IFrameWindow::windowList | IFrameWindow::minimizedIcon
    : IFrameWindow::minimizedIcon));

  IFrameWindow  dummy(WND_BANDIT_NETSCAPE, style);
  dummy.sizeTo(ISize(0,0));


  if (rc = this->loadDLL()) {
    _pobjectWindow = new IObjectWindow;
    _pnetscapeHandler = new BANNetscapeHandler(_pobjectWindow, *this);
    _pnetscapeHandler->handleEventsFor(_pobjectWindow);

    // Make sure that the window closes down the object window.
    BANCommandHandler cmdHandler(_pobjectWindow);
    cmdHandler.handleEventsFor(&dummy);

    // Start to process all the message send or posted to the objectwindow
    IThread::current().processMsgs();
  }

  return rc;
}

//***************************************************************************
// BANNetscape::insertTags
// Input parameters :
// The member inserts all the tags. (Uses the old functionallity.
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::handleTags(const IWindowHandle& frameHandle)
{
  ICurrentThread& currentThread(IThread::current());
  Boolean         guiRunning(currentThread.isGUIInitialized());

  if (!guiRunning)
    currentThread.initializeGUI();


  HWND    hwndFrame = frameHandle.asUnsigned();
  HWND    hwndMLE   = WinWindowFromID(hwndFrame, FID_CLIENT);
  if (hwndMLE == NULLHANDLE) {  // Most likely the toolbar was pressed.
    HWND hwndParent = WinQueryWindow(hwndFrame, QW_PARENT); // First to static
    hwndParent = WinQueryWindow(hwndParent, QW_PARENT);  // Then to the real WC_FRAME
    hwndMLE = WinWindowFromID(hwndParent, FID_CLIENT);
  }


  _pmleHandle = new IWindowHandle(hwndMLE);
  // Extract the temp text from the MLE

  if (_pmleHandle->asUnsigned() != 0) {
    this->saveClipboard();
    this->getMailText();

    _pmail = new MailHandler(_userIni, _mleContents, false, false, true);
    try {
      _ptagger = new MailTagger(_userIni);
    }
    catch (IException& exc)
     {
       return false;
     }
    // Mark the ones that are tagable.
    _ptagger->isTaglines(_pmail->tagMarkers());
    _pmail->insertTaglines(*_ptagger);

    this->setMailText();
    this->restoreClipboard();
    if (_pmail->changed())
      DosSleep(_userIni.pause()); // Use the default pause with Netscape also.
  }
  if (!guiRunning)
    currentThread.terminateGUI();
  return true;
}

//***************************************************************************
// BANNetscape::loadDLL()
// Input parameters :
// The member loads the dll, afterwards it load the routines used by the program
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::loadDLL()
{
  // First of all initialize the dll
  char    szLoadError[256];
  APIRET  rc;

  rc = DosLoadModule(szLoadError,
                     sizeof(szLoadError),
                     HOOKDLL,
                     &_hmod);
  if (rc == NO_ERROR) {
      rc = DosQueryProcAddr(_hmod,
                       0,
                       INITDLL,
                       (PFN*)&BANInitDLL);
  }
  if (rc == NO_ERROR) {
      rc = DosQueryProcAddr(_hmod,
                       0,
                       STARTINPUTHOOK,
                       (PFN*)&BANStartInputHook);
  }
  if (rc == NO_ERROR) {
      rc = DosQueryProcAddr(_hmod,
                       0,
                       STOPINPUTHOOK,
                       (PFN*)&BANStopInputHook);
  }
  if (rc == NO_ERROR) {
      rc = DosQueryProcAddr(_hmod,
                       0,
                       DESTROYDLL,
                       (PFN*)&BANDestroyDLL);
  }
  return rc == NO_ERROR ? true : false;
}

//***************************************************************************
// BANNetscape::~BANNetscape
// Input parameters :
// The destructs the object (default) and frees the DLL
// Returncodes : Boolean
//***************************************************************************

BANNetscape::~BANNetscape()
{
  DosFreeModule(_hmod);
}

//***************************************************************************
// BANNetscapeHandler::BANNetscapeHandler
// Input parameters :
// This member contructs the BANNetscapeHandler object.
// Returncodes :
//***************************************************************************

BANNetscapeHandler::BANNetscapeHandler(IObjectWindow* objectWindow, BANNetscape& netscape)
: _pobjectWindow(objectWindow)
, _netscape(netscape)
{
  // DLL Load.
  BANInitDLL(IThread::current().anchorBlock(), 34084, _pobjectWindow->handle());
  // DLL Load end

  // Start the hook.
  BANStartInputHook();
  // Hook started.
}

//***************************************************************************
// BANNetscapeHandler::dispatchHandlerEvent(IEvent& event)
// Input parameters :
// The member sends a message to the window handle.
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscapeHandler::dispatchHandlerEvent(IEvent& event)
{
  if (event.eventId() < WM_USER && event.eventId() != WM_QUIT) // To avoid testing
    return false;

  switch (event.eventId()) {
  case UM_COMMANDID_RECEIVED:  // The specified commadn id was received by Netscape.
    {
      BANStopInputHook();
      IWindowHandle  windowHandle(event.parameter1().asLong());
      _netscape.handleTags(event.parameter1().asLong());
      windowHandle.sendEvent(WM_COMMAND, IEventData(34084), event.parameter2());
      BANStartInputHook();
    }
    break;
  default:
    break;
  } // endswitch

  return false;
}

//***************************************************************************
// BANNetscape::getMailText
// Input parameters :
// The member extract the mailtext.
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::getMailText()
{

  _iptPrevAnchor = _pmleHandle->sendEvent(MLM_QUERYSEL, IEventData(MLFQS_ANCHORSEL)).asLong();
  _iptPrevCursor = _pmleHandle->sendEvent(MLM_QUERYSEL, IEventData(MLFQS_CURSORSEL)).asLong();
  long textLength   (_pmleHandle->sendEvent(MLM_QUERYTEXTLENGTH).asLong());

  _pmleHandle->sendEvent(MLM_DISABLEREFRESH);
  _pmleHandle->sendEvent(MLM_SETSEL, IEventData(0), IEventData(int(textLength)));
  _pmleHandle->sendEvent(MLM_COPY);

  _mleContents = _pclipboard->text();

  return true;
}

//***************************************************************************
// BANNetscape::setMailText
// Input parameters :
// The member extract the mailtext.
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::setMailText()
{

  // Insert the new text.
  _pclipboard->setText(_pmail->newMail());
  _pmleHandle->sendEvent(MLM_PASTE);

  // Restore the old cursor postion.
  _pmleHandle->sendEvent(MLM_SETSEL, IEventData(int(_iptPrevAnchor)), IEventData(int(_iptPrevCursor)));
  _pmleHandle->sendEvent(MLM_ENABLEREFRESH);

  return true;
}


//***************************************************************************
// BANNetscape::saveClipboard
// Input parameters :
// The member saves the clipboard, before changing it.
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::saveClipboard()
{
  _pclipboard = new IClipboard(_pobjectWindow->handle());

  if (_pclipboard->hasText())
    _clipboardText = _pclipboard->text();
  if (_pclipboard->hasBitmap())
    _pclipboardBitmap = new IBitmapHandle(_pclipboard->bitmap());

  return true;
}

//***************************************************************************
// BANNetscape::restoreClipboard
// Input parameters :
// The member restores the old clipboard
// Returncodes : Boolean
//***************************************************************************

Boolean BANNetscape::restoreClipboard()
{
  if (_clipboardText != IString()) // Old clipboard had text.
    _pclipboard->setText(_clipboardText);
  if (_pclipboardBitmap != 0) {    // Old clipboard was a bitmap
    _pclipboard->setBitmap(*_pclipboardBitmap);
    delete _pclipboardBitmap;
  }

  // Reset the old clipboard values.
  _clipboardText    = IString();
  _pclipboardBitmap = 0;

  return true;
}

//***************************************************************************
// BANCommandHandler::systemCommand
// Input parameters : ICommadnEvent
// This member closes down the object window.
// Returncodes : Boolean
//***************************************************************************

Boolean BANCommandHandler::systemCommand(ICommandEvent& cmdEvent)
{
  if (cmdEvent.commandId() == ISystemMenu::idClose) {
    BANStopInputHook();
    BANDestroyDLL();
    _pobjectWindow->close();
  }
  return false;
}

