//****************************************************************************
// File    : LOANNTBK.CPP
// Version : 0.01
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// IBM Internal Use Only 
// Copyright (c) IBM Corp. 1996          
// Developed by Nordic Business Fulfillment - Solutions Centre
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Purpose : 
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
// Vers     Date       Author    Comment                                  
// ----  ----------  ----------  ---------------------------------------------
// 0.01  1996-04-09  ALEXANDR    Created
//****************************************************************************

//* Include headers **********************************************************
#define INCL_WIN
#include <os2.h>
#include <stdio.h>
#include <math.h>

#include <iapp.hpp>
#include <ireslib.hpp>
#include <ithread.hpp>
#include <iprofile.hpp>

#include <ititle.hpp>
#include <imcelcv.hpp>
#include <isetcv.hpp>
#include <imle.hpp>
#include <inotebk.hpp>
#include <ipushbut.hpp>
#include <icombobx.hpp>
#include <ispinnum.hpp>
#include <istattxt.hpp>
#include <isysmenu.hpp>

#include <inotifev.hpp>
#include <ifont.hpp>
#include <iexcbase.hpp>
#include <imsgbox.hpp>
#include <idate.hpp>
#include <iprocadr.hpp>

#include "loanntbk.hpp"

#include "loanfram.hpp"
#include "loandobj.hpp"
#include "loan.rch"

#pragma pack(1)
#include <hapi_c.h>
#pragma pack()

//* Constants ****************************************************************
const unsigned long REPORTPAGELINES = 60;
const unsigned long LEN_COUNTRY     =  3;
const unsigned long LEN_CUSTNO      =  8;
const unsigned long LEN_LOANNO      =  8;
const unsigned long LEN_PERIOD      = 23;
const unsigned long LEN_DEBTBEF     = 12;
const unsigned long LEN_DEBTAFT     = 12;
const unsigned long LEN_AMORTIZ     = 12;
const unsigned long LEN_INTEREST    = 12;
const unsigned long LEN_AMOUNT      = 12;
const unsigned long LEN_INV         =  3;
const unsigned long LEN_CON         =  3;
const unsigned long LEN_AUT         =  3;
const unsigned long LEN_DOCNO       = 12;

const IString SPACE  (" ");
const IString NEWLINE("\n");

//* Typedefs *****************************************************************
typedef void (*_Far16 _Pascal HllapiFn)
  (USHORT *_Seg16, char *_Seg16, USHORT *_Seg16, USHORT *_Seg16);

/*****************************************************************************
// Constructor : LOANNotebook::LOANNotebook
*****************************************************************************/
LOANNotebook::LOANNotebook(LOANDataCnrObject* object,
                           Mode               mode  )
  : IFrameWindow((mode==New) ? FID_REPORT_NEW : FID_REPORT_OPEN,
                 IWindow::desktopWindow()                      ,
                 0                                             , 
                 IRectangle()                                  ,
                 IFrameWindow::defaultStyle()                  |
                 IFrameWindow::dialogBackground                |
                 IFrameWindow::shellPosition                   )
  , pObject      (object)
  , _mode        (mode  )
  , _isLayouted  (false )
  , _isHostActive(false )
  , resLib(IApplication::current().userResourceLibrary())
{}
        

/*****************************************************************************
// Static data LOANNotebook
*****************************************************************************/
INotificationId LOANNotebook :: Layouted = "LOANNotebook::Layouted"  ;


/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
long LOANNotebook::layout()
{
  if (!_isLayouted) {
    try {                                                                    
      long rc = layoutDetails();
                                                                             
      if (rc == 0) {                                                         
        _isLayouted = true;                                                  
        ICommandHandler::handleEventsFor(this);                              
        enableNotification();                                                
        notifyObservers(                                                     
          INotificationEvent(Layouted, *this, true, IEventData(_mode)));     
      } /* endif */                                                          
                                                                             
      return rc;                                                             
    } /* endtry */                                                           
    catch (IException& exc) {                                                
      IMessageBox(this)                                                      
        .setTitle("Application error")                                       
        .show(IString("Error ID : ")+IString(exc.errorId())+"\n"+exc.text(), 
              IMessageBox::warningIcon      | IMessageBox::okButton |        
              IMessageBox::applicationModal | IMessageBox::moveable );       
      return -1;                                                             
    } /* endcatch */                                                         
  } /* endif */
  return 0;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
Boolean LOANNotebook::command      (ICommandEvent& cmdEvt)
{
  switch (cmdEvt.commandId()) {
    case CID_NTB_PB_FETCH :
      IThread()
        .setStackSize(0x4000)
        .start(new IThreadMemberFn<LOANNotebook>(*this, handleFetch));
      break;

    case CID_NTB_PB_INVOICE :
      IThread()
        .setStackSize(0x4000)
        .start(new IThreadMemberFn<LOANNotebook>(*this, handleInvoice));
      break;

    case CID_NTB_PB_CONFIRM :
      IThread()
        .setStackSize(0x4000)
        .start(new IThreadMemberFn<LOANNotebook>(*this, handleConfirm));
      break;

    case CID_NTB_PB_AUTHORIZE :
      IThread()
        .setStackSize(0x4000)
        .start(new IThreadMemberFn<LOANNotebook>(*this, handleAuthorize));
      break;

    case CID_NTB_PB_CLOSE   :
      dismiss(CID_NTB_PB_CLOSE);
      IThread::current().stopProcessingMsgs();
      pObject->session   (session   ());
      break;

    case DID_CANCEL :
      dismiss(DID_CANCEL);
      IThread::current().stopProcessingMsgs();
      if (_mode == New) {
        pObject->setInUse(false);
        pObject->setOpen(false);
        pObject->discard();
      } else {
        pObject->session   (session   ());
      } /* endif */ 
      break;

    default: return false;
  } /* endswitch */

  return true;
}


/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
Boolean LOANNotebook::systemCommand(ICommandEvent& cmdEvt) 
{
  switch (cmdEvt.commandId()) {
    case SC_CLOSE :
      if (_isHostActive) return true;
      dismiss(SC_CLOSE);
      IThread::current().stopProcessingMsgs();
      if (_mode == New) {
        pObject->setInUse(false);
        pObject->setOpen(false);
        pObject->discard();
      } else {
        pObject->session   (session   ());
      } /* endif */ 
      return true;
          
    default       : return false;
  } /* endswitch */
}


/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
long LOANNotebook::layoutDetails ()
{
  //* Allocate controls ******************************************************
  pTitle = new ITitle(this);

  IMultiCellCanvas* pClient = 
    new IMultiCellCanvas(IC_FRAME_CLIENT_ID, this, this);

  pNotebook = new INotebook(0x1000, pClient, pClient, IRectangle(),
                            INotebook::polygonTabs          |
                            INotebook::spiralBinding        |
                            INotebook::statusTextRight      |
                            INotebook::tabTextCenter        |
                            INotebook::backPagesBottomRight | 
                            INotebook::majorTabsBottom      |
                            IWindow::visible                );

  pSettingsFrame = 
    new IFrameWindow((_mode==New) ?
                       FID_REPORT_NEW_SETTINGS :
                       FID_REPORT_OPEN_SETTINGS,
                     pNotebook, pNotebook,
                     IRectangle(), IWindow::visible);
                                
  pReportFrame = 
    new IFrameWindow((_mode==New) ?
                       FID_REPORT_NEW_REPORT :
                       FID_REPORT_OPEN_REPORT,
                     pNotebook, pNotebook,
                     IRectangle(), IWindow::visible);


  //* Set Auto Delete ********************************************************
  pTitle        ->setAutoDeleteObject();
  pClient       ->setAutoDeleteObject();
  pNotebook     ->setAutoDeleteObject();
  pSettingsFrame->setAutoDeleteObject();
  pReportFrame  ->setAutoDeleteObject();

  //* Support data ***********************************************************
  ISize defaultCell(IMultiCellCanvas::defaultCell());

  //* Init title *************************************************************
  if (_mode == Open) setOpenTitle();

  //* Init frames ************************************************************
  pSettingsFrame->setClient(layoutSettings(pSettingsFrame));
  pReportFrame  ->setClient(layoutReport  (pReportFrame  ));

  //* Init Notebook **********************************************************
  IFont noteFont(pNotebook);                                      
  int maxTabWidth = 0;                                            
                                                                  
  INotebook::PageSettings                                         
    pageSettings(INotebook::PageSettings::autoPageSize |
                 INotebook::PageSettings::majorTab     |
                 INotebook::PageSettings::statusTextOn );

  pageSettings.setTabText(STR_NTB_SETTINGS_TAB);
  pageSettings.setStatusText(pageSettings.tabText() + " - Page 1 of 1");
  pNotebook->addLastPage(pageSettings, pSettingsFrame),
  maxTabWidth =
    max((int)maxTabWidth, (int)noteFont.minTextWidth(pageSettings.tabText()));

  pageSettings.setTabText(STR_NTB_REPORT_TAB);
  pageSettings.setStatusText(pageSettings.tabText() + " - Page 1 of 1");
  pNotebook->addLastPage(pageSettings, pReportFrame),
  maxTabWidth =
    max((int)maxTabWidth, (int)noteFont.minTextWidth(pageSettings.tabText()));

  pNotebook->setMajorTabSize(
    ISize(maxTabWidth, noteFont.maxCharHeight()) + ISize(10,10));

  pNotebook->setBackgroundColor        (this->backgroundColor());
  pNotebook->setMajorTabBackgroundColor(this->backgroundColor());
  pNotebook->setMinorTabBackgroundColor(this->backgroundColor());
  pNotebook->setPageBackgroundColor    (this->backgroundColor());

  //* Init Client Canvas *****************************************************
  (*pClient)
    .addToCell(pNotebook             , 1, 1, 1, 1)
    .addToCell(layoutButtons(pClient), 1, 2, 1, 1)
    .setColumnWidth(1, defaultCell.width() , true ) 
    .setRowHeight  (1, defaultCell.height(), true );

  //* Set Client *************************************************************
  setClient(pClient);

  return 0;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IMultiCellCanvas* LOANNotebook::layoutSettings(IWindow* parentAndOwner)
{
  const ISize defaultCell(IMultiCellCanvas::defaultCell());

  //* Allocate controls ******************************************************
  pSettingsCanvas = 
    new IMultiCellCanvas(IC_FRAME_CLIENT_ID, parentAndOwner, parentAndOwner);
                                   
  pscCountry = 
    new ISetCanvas(CID_NTB_CV_COUNTRY, pSettingsCanvas, pSettingsCanvas);
  pscPeriod  = 
    new ISetCanvas(CID_NTB_CV_PERIOD , pSettingsCanvas, pSettingsCanvas);
  pscSession = 
    new ISetCanvas(CID_NTB_CV_SESSION, pSettingsCanvas, pSettingsCanvas);

  pcbCountry = 
    new IComboBox(CID_NTB_CB_COUNTRY, pscCountry     , pscCountry     ,
                  IRectangle(), 
                  IComboBox ::classDefaultStyle &
                  ~IComboBox::simpleType        | 
                  IComboBox ::dropDownListType  ); 

  IStaticText* pstYear = 
    new IStaticText(CID_NTB_ST_YEAR, pscPeriod, pscPeriod);
  pnsbYear = new INumericSpinButton(CID_NTB_SB_YEAR, pscPeriod, pscPeriod,
                                    IRectangle(),
                                    INumericSpinButton::classDefaultStyle |
                                    INumericSpinButton::padWithZeros      |
                                    INumericSpinButton::readOnly          );

  IStaticText* pstMonth = 
    new IStaticText(CID_NTB_ST_MONTH, pscPeriod, pscPeriod);
  pnsbMonth = new INumericSpinButton(CID_NTB_SB_MONTH, pscPeriod, pscPeriod, 
                                     IRectangle(),
                                     INumericSpinButton::classDefaultStyle|
                                     INumericSpinButton::padWithZeros     |
                                     INumericSpinButton::readOnly         );

  pcbSession = new IComboBox(CID_NTB_CB_SESSION, pscSession, pscSession,
                             IRectangle(), 
                             IComboBox ::classDefaultStyle &
                             ~IComboBox::simpleType        | 
                             IComboBox ::dropDownListType  ); 

  //* Set auto delete ********************************************************
  pSettingsCanvas->setAutoDeleteObject();
  pscCountry     ->setAutoDeleteObject();
  pscPeriod      ->setAutoDeleteObject();
  pscSession     ->setAutoDeleteObject();
  pcbCountry     ->setAutoDeleteObject();
  pstYear        ->setAutoDeleteObject();   
  pnsbYear       ->setAutoDeleteObject();
  pstMonth       ->setAutoDeleteObject();   
  pnsbMonth      ->setAutoDeleteObject();
  pcbSession     ->setAutoDeleteObject();   

  //* Init settings page *****************************************************
  pcbCountry->addAsLast(resLib.loadString(STR_FINLAND));
  // and more

  (*pcbCountry)
    .select(0)    //should be changed for more countries
    .setLimit(12)
    .enableTabStop()
    .enableGroup()
    .setFocus()
    .enable(_mode==New);

  pstYear->setText(pstYear   ->id());

  long year = (_mode == New) ?
                IDate::today().year() :
                pObject->parameters().subString(1,4).asInt();

  (*pnsbYear)
    .setRange(IRange(year-4, year+5))
    .spinTo(year)
    .setLimit(4)
    .enableTabStop()
    .enable(_mode==New);

  pstMonth  ->setText(pstMonth  ->id());

  long month = (_mode == New) ?
                 IDate::today().monthOfYear() :
                 pObject->parameters().subString(5,2).asInt();

  (*pnsbMonth)
    .setRange(IRange(1,12))
    .spinTo(month)
    .setLimit(2)
    .enableTabStop()
    .enable(_mode==New);

  fillSession(pcbSession);
  if (pcbSession->count() > 0) {
    IString session = (_mode==New) ?
                      IString("") :
                      ((pObject->session() != "") ?
                        pObject->session() : 
                        (IProfile("LOAN.INI")
                           .containsKeyName("SESSION", "DEFAULT") ?
                         IProfile("LOAN.INI") 
                           .elementWithKey("SESSION", "DEFAULT") :
                         IString("")));

    long selection = pcbSession->locateText(session);
    if (selection == IComboBox::notFound) 
      selection = pcbSession->count() - 1;

    (*pcbSession)        
      .select(selection)
      .setLimit(4)
      .enableTabStop();
  } else {
    pcbSession->addAsFirst(STR_NTB_NO_SESSIONS);
    (*pcbSession)
      .select(0)
      .enable(false);
  } /* endif */

  pscCountry->setText(pscCountry->id());
  pscPeriod ->setText(pscPeriod ->id());
  pscSession->setText(pscSession->id());

  if (_mode == New) {
    (*pSettingsCanvas)
      .addToCell(pscCountry, 2, 2, 1, 1)
      .addToCell(pscPeriod , 4, 2, 1, 1)
      .setColumnWidth(1, defaultCell.width() , true ) 
      .setColumnWidth(5, defaultCell.width() , true ) 
      .setRowHeight  (1, defaultCell.height(), true ) 
      .setRowHeight  (3, defaultCell.height(), true );
  } else {
    (*pSettingsCanvas)
      .addToCell(pscCountry, 2, 2, 1, 1)
      .addToCell(pscPeriod , 4, 2, 1, 1)
      .addToCell(pscSession, 6, 2, 1, 1)
      .setColumnWidth(1, defaultCell.width() , true ) 
      .setColumnWidth(7, defaultCell.width() , true ) 
      .setRowHeight  (1, defaultCell.height(), true ) 
      .setRowHeight  (3, defaultCell.height(), true );
  } /* endif */

  return pSettingsCanvas;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IMultiCellCanvas* LOANNotebook::layoutReport(IWindow* parentAndOwner)
{                      
  const ISize defaultCell(IMultiCellCanvas::defaultCell());

  //* Allocate controls ******************************************************
  IMultiCellCanvas* pReportCanvas = 
    new IMultiCellCanvas(IC_FRAME_CLIENT_ID, parentAndOwner, parentAndOwner);
  
  pmleReport = 
    new IMultiLineEdit(CID_NTB_MLE_REPORT, pReportCanvas, pReportCanvas,
                       IRectangle(),
                       IMultiLineEdit::classDefaultStyle |
                       IMultiLineEdit::horizontalScroll  );

  //* Set auto delete ********************************************************
  pReportCanvas->setAutoDeleteObject();
  pmleReport   ->setAutoDeleteObject();

  //* Init mle ***************************************************************
  (*pmleReport)
    .enableWordWrap(false)
    .disableDataUpdate()
    .setFont(IFont("Courier", 8));

  //* Init canvas ************************************************************
  (*pReportCanvas)
    .addToCell(pmleReport, 1, 1, 1, 1)
    .setColumnWidth(1, defaultCell.width() , true ) 
    .setRowHeight  (1, defaultCell.height(), true );

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

  return pReportCanvas;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IMultiCellCanvas* LOANNotebook::layoutButtons (IWindow* parentAndOwner)
{
  ISize defaultCell(IMultiCellCanvas::defaultCell());

  //* Allocate controls ******************************************************
  buttonsCanvas = new IMultiCellCanvas(0x1001, parentAndOwner, parentAndOwner);
  ppbFetch     = new IPushButton(CID_NTB_PB_FETCH    , buttonsCanvas, buttonsCanvas);
  ppbCancel    = new IPushButton(DID_CANCEL          , buttonsCanvas, buttonsCanvas);
  ppbInvoice   = new IPushButton(CID_NTB_PB_INVOICE  , buttonsCanvas, buttonsCanvas);
  ppbConfirm   = new IPushButton(CID_NTB_PB_CONFIRM  , buttonsCanvas, buttonsCanvas);
  ppbAuthorize = new IPushButton(CID_NTB_PB_AUTHORIZE, buttonsCanvas, buttonsCanvas);
  ppbClose     = new IPushButton(CID_NTB_PB_CLOSE    , buttonsCanvas, buttonsCanvas);
  ppbHelp      = new IPushButton(DID_HELP_PB         , buttonsCanvas, buttonsCanvas);

  //* Set auto delete ********************************************************
  buttonsCanvas->setAutoDeleteObject();
  ppbFetch     ->setAutoDeleteObject();
  ppbCancel    ->setAutoDeleteObject();
  ppbInvoice   ->setAutoDeleteObject();
  ppbConfirm   ->setAutoDeleteObject();
  ppbAuthorize ->setAutoDeleteObject();
  ppbClose     ->setAutoDeleteObject();
  ppbHelp      ->setAutoDeleteObject();

  //* Init Buttons ***********************************************************
  (*ppbHelp     ) 
    .enableHelp()
    .setText(ppbHelp     ->id()) 
    .enableMouseClickFocus(false)
    .enableTabStop();

  //* Init Button Canvas *****************************************************
  if (_mode == New) {
    (*ppbFetch    ).setText(ppbFetch ->id()).enableTabStop().enableGroup();
    (*ppbCancel   ).setText(ppbCancel->id()).enableTabStop();

    long  buttonWidth = 0;
    buttonWidth = (buttonWidth < ppbFetch    ->minimumSize().width()) ? ppbFetch    ->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbCancel   ->minimumSize().width()) ? ppbCancel   ->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbHelp     ->minimumSize().width()) ? ppbHelp     ->minimumSize().width() : buttonWidth;

    (*buttonsCanvas)
      .addToCell(ppbFetch  , 2, 2, 1, 1)
      .addToCell(ppbCancel , 4, 2, 1, 1)
      .addToCell(ppbHelp   , 6, 2, 1, 1)
      .setColumnWidth(1, defaultCell.width() , true ) 
      .setColumnWidth(2, buttonWidth         , false) 
      .setColumnWidth(4, buttonWidth         , false) 
      .setColumnWidth(6, buttonWidth         , false) 
      .setColumnWidth(7, defaultCell.width() , true ) 
      .setRowHeight  (3, defaultCell.height(), false);
  } else {
    (*ppbInvoice  ).setText(ppbInvoice  ->id()).enableTabStop().enableGroup();
    (*ppbConfirm  ).setText(ppbConfirm  ->id()).enableTabStop();
    (*ppbAuthorize).setText(ppbAuthorize->id()).enableTabStop();
    (*ppbClose    ).setText(ppbClose    ->id()).enableTabStop();

    long  buttonWidth = 0;
    buttonWidth = (buttonWidth < ppbInvoice  ->minimumSize().width()) ? ppbInvoice  ->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbConfirm  ->minimumSize().width()) ? ppbConfirm  ->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbAuthorize->minimumSize().width()) ? ppbAuthorize->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbClose    ->minimumSize().width()) ? ppbClose    ->minimumSize().width() : buttonWidth;
    buttonWidth = (buttonWidth < ppbHelp     ->minimumSize().width()) ? ppbHelp     ->minimumSize().width() : buttonWidth;

    (*buttonsCanvas)
      .addToCell(ppbInvoice  ,  2, 2, 1, 1)
      .addToCell(ppbConfirm  ,  4, 2, 1, 1)
      .addToCell(ppbAuthorize,  6, 2, 1, 1)
      .addToCell(ppbClose    ,  8, 2, 1, 1)
      .addToCell(ppbHelp     , 10, 2, 1, 1)
      .setColumnWidth( 1, defaultCell.width() , true ) 
      .setColumnWidth( 2, buttonWidth         , false) 
      .setColumnWidth( 4, buttonWidth         , false) 
      .setColumnWidth( 6, buttonWidth         , false) 
      .setColumnWidth( 8, buttonWidth         , false) 
      .setColumnWidth(10, buttonWidth         , false) 
      .setColumnWidth(11, defaultCell.width() , true ) 
      .setRowHeight  ( 3, defaultCell.height(), false);
  } /* endif */

  return buttonsCanvas;
}


/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::handleFetch()
{
  pObject->country   (country   ());
  pObject->parameters(parameters());
  pObject->session   (session   ());

  enableControlsForFetch(false);

  long rc = pObject->fetch();
  if (rc == 0) {
    layoutFetched();
  } else {
    IString title( (rc == LOANDataCnrObject::DATASET_ALREADY_EXISTS) ?
                    resLib.loadString(MSG_REPORT_ALREADY_EXISTS_TITLE) :
                    resLib.loadString(MSG_FETCH_UNSUCCESFUL_TITLE) );

    IString text ( (rc == LOANDataCnrObject::DATASET_ALREADY_EXISTS) ?
                      resLib.loadString(MSG_REPORT_ALREADY_EXISTS_TEXT) :
                      resLib.loadString(MSG_FETCH_UNSUCCESFUL_TEXT) );

    text
      .change("%c", resLib.loadString(country().asInt()))
      .change("%y", parameters().subString( 1, 4))
      .change("%m", parameters().subString( 5, 2)) 
      .change("%r", IString(rc)) ; 

    IMessageBox* pMsgBox = new IMessageBox(this);

    pMsgBox->setTitle(title);
    pMsgBox->show(text, 
                  IMessageBox::warningIcon      | IMessageBox::okButton |
                  IMessageBox::applicationModal | IMessageBox::moveable );       

    delete pMsgBox;

    enableControlsForFetch(true);
  } /* endif */
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::handleInvoice  ()
{
  enableControlsForHost(false);
  pObject->session   (session   ());
  pObject->invoice(LOANDataCnrObject::Notebook);
  pObject->dataSet()->load();
  fillReportPages();
  enableControlsForHost(true);
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::handleConfirm  ()
{
  enableControlsForHost(false);
  pObject->session   (session   ());
  pObject->confirm(LOANDataCnrObject::Notebook);
  pObject->dataSet()->load();
  fillReportPages();
  enableControlsForHost(true);
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::handleAuthorize()
{
  enableControlsForHost(false);
  pObject->session   (session   ());
  pObject->authorize(LOANDataCnrObject::Notebook);
  pObject->dataSet()->load();
  fillReportPages();
  enableControlsForHost(true);
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::enableControlsForFetch(Boolean enable)
{
  ppbFetch  ->enable(enable);

  pcbCountry->enable(enable);
  pnsbYear  ->enable(enable);
  pnsbMonth ->enable(enable);

  if (enable) {
    setMousePointer(0);
    pSettingsFrame->setMousePointer(0);
    pReportFrame  ->setMousePointer(0);
  } else {
    ISystemPointerHandle pointerHandle(ISystemPointerHandle::wait);
    setMousePointer(pointerHandle);
    pSettingsFrame->setMousePointer(pointerHandle);
    pReportFrame  ->setMousePointer(pointerHandle);
  } /* endif */
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::enableControlsForHost(Boolean enable)
{                      
  _isHostActive = !enable;
  ISystemMenu(this).enableItem(ISystemMenu::idClose, enable);

  ppbInvoice  ->enable(enable);
  ppbConfirm  ->enable(enable);
  ppbAuthorize->enable(enable);
  ppbClose    ->enable(enable);

  if (enable) {
    setMousePointer(0);
    pSettingsFrame->setMousePointer(0);
    pReportFrame  ->setMousePointer(0);
  } else {
    ISystemPointerHandle pointerHandle(ISystemPointerHandle::wait);
    setMousePointer(pointerHandle);
    pSettingsFrame->setMousePointer(pointerHandle);
    pReportFrame  ->setMousePointer(pointerHandle);
  } /* endif */
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::layoutFetched  ()
{                      
  ISize defaultCell(IMultiCellCanvas::defaultCell());

  fillReportPages();

  buttonsCanvas->removeFromCell(2, 2);
  buttonsCanvas->removeFromCell(4, 2);
  buttonsCanvas->removeFromCell(6, 2);
  (*ppbFetch ).disable().hide();
  (*ppbCancel).disable().hide();

  (*ppbInvoice  ).setText(ppbInvoice  ->id()).enableTabStop().enableGroup();
  (*ppbConfirm  ).setText(ppbConfirm  ->id()).enableTabStop();
  (*ppbAuthorize).setText(ppbAuthorize->id()).enableTabStop();
  (*ppbClose    ).setText(ppbClose    ->id()).enableTabStop();

  long  buttonWidth = 0;
  buttonWidth = (buttonWidth < ppbInvoice  ->minimumSize().width()) ? ppbInvoice  ->minimumSize().width() : buttonWidth;
  buttonWidth = (buttonWidth < ppbConfirm  ->minimumSize().width()) ? ppbConfirm  ->minimumSize().width() : buttonWidth;
  buttonWidth = (buttonWidth < ppbAuthorize->minimumSize().width()) ? ppbAuthorize->minimumSize().width() : buttonWidth;
  buttonWidth = (buttonWidth < ppbClose    ->minimumSize().width()) ? ppbClose    ->minimumSize().width() : buttonWidth;
  buttonWidth = (buttonWidth < ppbHelp     ->minimumSize().width()) ? ppbHelp     ->minimumSize().width() : buttonWidth;

  (*buttonsCanvas)
    .addToCell(ppbInvoice  ,  2, 2, 1, 1)
    .addToCell(ppbConfirm  ,  4, 2, 1, 1)
    .addToCell(ppbAuthorize,  6, 2, 1, 1)
    .addToCell(ppbClose    ,  8, 2, 1, 1)
    .addToCell(ppbHelp     , 10, 2, 1, 1)
    .setColumnWidth( 1, defaultCell.width() , true ) 
    .setColumnWidth( 2, buttonWidth         , false) 
    .setColumnWidth( 4, buttonWidth         , false) 
    .setColumnWidth( 6, buttonWidth         , false) 
    .setColumnWidth( 7, defaultCell.width() , false) 
    .setColumnWidth( 8, buttonWidth         , false) 
    .setColumnWidth(10, buttonWidth         , false) 
    .setColumnWidth(11, defaultCell.width() , true ) 
    .setRowHeight  ( 3, defaultCell.height(), false)
    .refresh();

  (*pSettingsCanvas)
    .addToCell(pscSession, 6, 2, 1, 1)
    .setColumnWidth(5, defaultCell.width() , false) 
    .setColumnWidth(7, defaultCell.width() , true )
    .refresh();

  this          ->setId(FID_REPORT_OPEN         );
  pSettingsFrame->setId(FID_REPORT_OPEN_SETTINGS);
  pReportFrame  ->setId(FID_REPORT_OPEN_REPORT  );
  _mode = Open;

  setOpenTitle();
  pObject->setObjectName();

  setMousePointer(0);
  pSettingsFrame->setMousePointer(0);
  pReportFrame  ->setMousePointer(0);
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::fillReportPages()
{                      
  if (pObject->dataSet()) {

    IString  reportLines("");
    unsigned long lines  = 0;

    double amortization  = 0;
    double interest      = 0;
    double amount        = 0;

    WinEnableWindowUpdate(pmleReport->handle(), FALSE);
    pmleReport->removeAll();

    LOANDataSet::Cursor cursor(*(pObject->dataSet()));
    for (cursor.setToFirst(); cursor.isValid(); cursor.setToNext()) {
      LOANDataRowPtr& dataRow(pObject->dataSet()->elementAt(cursor));

      if (lines == 0) {
        reportLines += addHeaderToReport();
        lines += 3;
      } /* endif */

      reportLines  += addRowToReport(dataRow);

      amortization += dataRow->amortiz (); 
      interest     += dataRow->interest(); 
      amount       += dataRow->amount  ();

      lines = (lines + 1) % REPORTPAGELINES;

      if (lines == 0) {
        pmleReport->addLineAsLast(reportLines);
        reportLines = "";
      } /* endif */

    } /* endfor */

    reportLines += 
      addTotalsToReport(lines,
                        pObject->dataSet()->numberOfElements(),
                        amortization,
                        interest,    
                        amount);

    pmleReport->addLineAsLast(reportLines);

    WinEnableWindowUpdate(pmleReport->handle(), TRUE);

  } /* endif */
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::addHeaderToReport()
{
  static IString                                                  
    header(resLib.loadString(STR_COUNTRY ).center(LEN_COUNTRY ) + SPACE +
           resLib.loadString(STR_CUSTNO  ).center(LEN_CUSTNO  ) + SPACE +
           resLib.loadString(STR_LOANNO  ).center(LEN_LOANNO  ) + SPACE +
           resLib.loadString(STR_PERIOD  ).center(LEN_PERIOD  ) + SPACE +
           resLib.loadString(STR_DEBTBEF ).center(LEN_DEBTBEF ) + SPACE +
           resLib.loadString(STR_DEBTAFT ).center(LEN_DEBTAFT ) + SPACE +
           resLib.loadString(STR_AMORTIZ ).center(LEN_AMORTIZ ) + SPACE +
           resLib.loadString(STR_INTERST ).center(LEN_INTEREST) + SPACE +
           resLib.loadString(STR_AMOUNT  ).center(LEN_AMOUNT  ) + SPACE +
           resLib.loadString(STR_INV     ).center(LEN_INV     ) + SPACE +
           resLib.loadString(STR_CON     ).center(LEN_CON     ) + SPACE +
           resLib.loadString(STR_AUT     ).center(LEN_AUT     ) + SPACE +
           resLib.loadString(STR_DOCNO   ).center(LEN_DOCNO   ) + NEWLINE);

  static IString 
    sep   (IString("-").copy(LEN_COUNTRY ) + SPACE +
           IString("-").copy(LEN_CUSTNO  ) + SPACE +
           IString("-").copy(LEN_LOANNO  ) + SPACE +
           IString("-").copy(LEN_PERIOD  ) + SPACE +
           IString("-").copy(LEN_DEBTBEF ) + SPACE +
           IString("-").copy(LEN_DEBTAFT ) + SPACE +
           IString("-").copy(LEN_AMORTIZ ) + SPACE +
           IString("-").copy(LEN_INTEREST) + SPACE +
           IString("-").copy(LEN_AMOUNT  ) + SPACE +
           IString("-").copy(LEN_INV     ) + SPACE +
           IString("-").copy(LEN_CON     ) + SPACE +
           IString("-").copy(LEN_AUT     ) + SPACE +
           IString("-").copy(LEN_DOCNO   ) + NEWLINE);
            
  static IString 
    headerLines (SPACE + NEWLINE + header + sep);

  return headerLines;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::addRowToReport   (LOANDataRowPtr& dataRow)
{
  return
    IString(dataRow->country ()).leftJustify(LEN_COUNTRY ) + SPACE +
    IString(dataRow->custno  ()).leftJustify(LEN_CUSTNO  ) + SPACE +
    IString(dataRow->loanno  ()).leftJustify(LEN_LOANNO  ) + SPACE +
                                                             
    IString(dataRow->fromdate().asString("%Y-%m-%d") + " - " +
             dataRow->todate().asString("%Y-%m-%d")
           ).leftJustify(LEN_PERIOD  )                     + SPACE +

    formatDouble(dataRow->debtbefp(), LEN_DEBTBEF  , 0) + SPACE +
    formatDouble(dataRow->debtaftp(), LEN_DEBTAFT  , 0) + SPACE +

    formatDouble(dataRow->amortiz (), LEN_AMORTIZ  , 0) + SPACE +
    formatDouble(dataRow->interest(), LEN_INTEREST , 0) + SPACE +
    formatDouble(dataRow->amount  (), LEN_AMOUNT   , 0) + SPACE +

    IString(dataRow->isInvoiced  () ? "Y" : "N").center(LEN_INV) + SPACE +
    IString(dataRow->isConfirmed () ? "Y" : "N").center(LEN_CON) + SPACE +
    IString(dataRow->isAuthorized() ? "Y" : "N").center(LEN_AUT) + SPACE +

    IString(dataRow->docno   ()).leftJustify(LEN_DOCNO   ) + NEWLINE;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::addTotalsToReport(unsigned long lines,
                                        unsigned long count,
                                        double amortization,
                                        double interest    ,
                                        double amount      )
{                 
  IString 
    sep   (IString("-").copy(LEN_COUNTRY ) + SPACE +
           IString("-").copy(LEN_CUSTNO  ) + SPACE +
           IString("-").copy(LEN_LOANNO  ) + SPACE +
           IString("-").copy(LEN_PERIOD  ) + SPACE +
           IString("-").copy(LEN_DEBTBEF ) + SPACE +
           IString("-").copy(LEN_DEBTAFT ) + SPACE +
           IString("-").copy(LEN_AMORTIZ ) + SPACE +
           IString("-").copy(LEN_INTEREST) + SPACE +
           IString("-").copy(LEN_AMOUNT  ) + SPACE +
           IString("-").copy(LEN_INV     ) + SPACE +
           IString("-").copy(LEN_CON     ) + SPACE +
           IString("-").copy(LEN_AUT     ) + SPACE +
           IString("-").copy(LEN_DOCNO   ) + NEWLINE);

  IString 
    totals(IString(' ').copy(LEN_COUNTRY ) + SPACE +
           formatDouble(count, LEN_CUSTNO, 0)
             .stripLeading(' ')
             .center(LEN_CUSTNO)           + SPACE +
           IString(' ').copy(LEN_LOANNO  ) + SPACE +
           IString(' ').copy(LEN_PERIOD  ) + SPACE +
           IString(' ').copy(LEN_DEBTBEF ) + SPACE +
           IString(' ').copy(LEN_DEBTAFT ) + SPACE +
           formatDouble(amortization, LEN_AMORTIZ , 0) + SPACE +
           formatDouble(interest    , LEN_INTEREST, 0) + SPACE +
           formatDouble(amount      , LEN_AMOUNT  , 0) + SPACE +
           IString(' ').copy(LEN_INV     ) + SPACE +
           IString(' ').copy(LEN_CON     ) + SPACE +
           IString(' ').copy(LEN_AUT     ) + SPACE +
           IString(' ').copy(LEN_DOCNO   ) + NEWLINE);

  return sep + totals;
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::country   () 
{
  if (pcbCountry->text() == resLib.loadString(STR_FINLAND)) return "702";
  // and more

  return "702";
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::parameters() 
{
  return IString(pnsbYear ->value()).rightJustify(4,'0')+ 
         IString(pnsbMonth->value()).rightJustify(2,'0');
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::session   () 
{
  return (pcbSession->text().length()==1) ? pcbSession->text() : IString("");
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::setOpenTitle   ()
{
  pTitle->setTitleText(
    resLib
      .loadString(FID_REPORT_OPEN)
      .change("%c", resLib.loadString(pObject->country().asInt()))
      .change("%p", pObject->parameters().subString( 1, 4) + " - " +
                    pObject->parameters().subString( 5, 2)));
}

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
void LOANNotebook::fillSession(IComboBox* pcbSession)
{
  try {
    IProcedureAddress<HllapiFn> hllapi("HLLAPI", "ACS3EHAP");

    USHORT fn   = (USHORT)HA_QUERY_SESSIONS;
    qses_struct data[27];
    USHORT ln   = (USHORT)sizeof(data);
    USHORT rc   = (USHORT)0;
 
    hllapi(&fn, (char*)&data, &ln, &rc);
  
    for (int i = 1; i < ln ; i++)
      pcbSession->addAsLast(IString(data[i].qses_shortname));
  } /* endtry */
  catch (IException& exc) {
  } /* endcatch */
} 

/*****************************************************************************
// Function : LOANNotebook::
*****************************************************************************/
IString LOANNotebook::formatDouble
  (double source, int length, int decimals, char tsep, char dsep)
{
  char temp[32]; 
  sprintf(temp, "%*.*f", length, decimals, source);

  int offset = length - decimals - 1;

  if (decimals > 0) {
    temp[offset] = dsep;
    offset--;
  } /* endif */
               
  for (int y = log10(source); y > 2; y--) {
    int move = y/3;
    temp[offset-y-move] = temp[offset-y];
    if (y%3==0) temp[offset-y-move+1] = tsep;
  } /* endfor */

  return temp;
}
