//-----------------------------------------------------------------------------
/*
 * Description: This file contains the class AxMenuConfigPlugin
 *
 * See the file README in the main directory for a description of
 * this software, copyright information, and how to reach the author.
 *
 * Author: alex
 * Date:   15.11.2003
 *
 * Last modfied:
 *   $Author: alex $
 *   $Date: 2004/05/31 12:52:20 $
 *   $Revision: 1.7 $
 */
//-----------------------------------------------------------------------------

//=============================================================================
//     includes
//=============================================================================

//----- multiple defs of swap() workaround ------------------------------------
#include "AxPluginGlobals.h"

//----- qt --------------------------------------------------------------------
//----- CORBA -----------------------------------------------------------------
//----- ICE -------------------------------------------------------------------
//----- C++ -------------------------------------------------------------------
//----- C ---------------------------------------------------------------------
//----- vdr -------------------------------------------------------------------
#include <vdr/tools.h>
#include <vdr/i18n.h>
#include <vdr/interface.h>
#include <vdr/menuitems.h>

//----- AxLib -----------------------------------------------------------------
#include <Ax/Tools/Trace.h>
// #include <Ax/Tools/TraceOn.h>
#include <Ax/Mail/MailBoxSetup.h>

//----- local plugin ----------------------------------------------------------
#include "AxVdrTools.h"
#include "AxPluginSetup.h"
#include "AxMenuConfigMailBox.h"
#include "AxMenuConfigCommon.h"
#include "AxMenuConfigPlugin.h"
#include "AxPluginMailBox.h"
#include "AxMenuCode.h"

//----- locals ----------------------------------------------------------------

//=============================================================================
//     using namespaces
//=============================================================================
using namespace std;
using namespace Ax;

//=============================================================================
//     class AxMailBoxSetupItem
//=============================================================================
class AxMailBoxSetupItem : public cOsdItem
{
  typedef cOsdItem PARENT;

  public:
    //-------------------------------------------------------------------------
    //     AxMailBoxSetupItem::AxMailBoxSetupItem()
    //-------------------------------------------------------------------------
    AxMailBoxSetupItem(Ax::Mail::MailBoxSetup *aMBSetup, eOSState State = osUnknown);

    //-------------------------------------------------------------------------
    //     AxMailBoxSetupItem::~AxMailBoxSetupItem()
    //-------------------------------------------------------------------------
    virtual ~AxMailBoxSetupItem();

    //-------------------------------------------------------------------------
    //     AxMailBoxSetupItem::getMBSetup()
    //-------------------------------------------------------------------------
    Ax::Mail::MailBoxSetup *getMBSetup();

    //-------------------------------------------------------------------------
    //     AxMailBoxSetupItem::Set()
    //-------------------------------------------------------------------------
    virtual void Set(void);

  private:
    //-------------------------------------------------------------------------
    //     attributes
    //-------------------------------------------------------------------------
    Ax::Mail::MailBoxSetup *myMBSetup;
}; // class AxMailBoxSetupItem

//-----------------------------------------------------------------------------
//     AxMailBoxSetupItem::AxMailBoxSetupItem()
//-----------------------------------------------------------------------------
AxMailBoxSetupItem::AxMailBoxSetupItem(Ax::Mail::MailBoxSetup *aMBSetup, eOSState State)
                  : PARENT(State)
                  , myMBSetup(aMBSetup)
{
} // AxMailBoxSetupItem::AxMailBoxSetupItem()

//-----------------------------------------------------------------------------
//     AxMailBoxSetupItem::~AxMailBoxSetupItem()
//-----------------------------------------------------------------------------
AxMailBoxSetupItem::~AxMailBoxSetupItem()
{
} // AxMailBoxSetupItem::~AxMailBoxSetupItem()

//-----------------------------------------------------------------------------
//     AxMailBoxSetupItem::getMBSetup()
//-----------------------------------------------------------------------------
Ax::Mail::MailBoxSetup *AxMailBoxSetupItem::getMBSetup()
{
  return myMBSetup;
} // AxMailBoxSetupItem::getMBSetup()

//-----------------------------------------------------------------------------
//     AxMBSetupItem::Set()
//-----------------------------------------------------------------------------
void AxMailBoxSetupItem::Set()
{
  wsdebug(("- AxMBSetupItem::Set() '%s'", myMBSetup->AccountName));
  SetText(myMBSetup->AccountName, true);
} // AxMailBoxSetupItem::Set()

//=============================================================================
//     class AxMenuConfigPlugin
//=============================================================================

//-----------------------------------------------------------------------------
//     AxMenuConfigPlugin::AxMenuConfigPlugin()
//-----------------------------------------------------------------------------
AxMenuConfigPlugin::AxMenuConfigPlugin(AxPluginMailBox *thePlugin, AxPluginSetup *theSetup)
                  : myPlugin          (thePlugin)
                  , myOldSetup        (theSetup )
                  , myNewSetup        (*theSetup)
                  , myLockAction      (ACT_NONE )
                  , myLockCodeIsOk    (false    )
                  , myLockMailBoxSetup(0        )
{
  wsdebug(("> AxMenuConfigPlugin::AxMenuConfigPlugin()"));

  //----- Common settings ------------------------------------------------
  Add(new cOsdItem(tr("General settings")));

  //----- mail accounts --------------------------------------------------
  AddSeparator(tr("Mail accounts"));

  for (Mail::MailBoxSetupList::iterator anIter  = myNewSetup.Accounts.begin();
                                        anIter != myNewSetup.Accounts.end();
                                      ++anIter)
  {
    AxMailBoxSetupItem *anItem = new AxMailBoxSetupItem(*anIter);
    Add(anItem);
    anItem->Set();
  } // for

  SetCurrent(Get(0));
  setButtons(1);

  wsdebug(("< AxMenuConfigPlugin::AxMenuConfigPlugin()"));
} // AxMenuConfigPlugin::AxMenuConfigPlugin()

//-----------------------------------------------------------------------------
//     AxMenuConfigPlugin::~AxMenuConfigPlugin()
//-----------------------------------------------------------------------------
AxMenuConfigPlugin::~AxMenuConfigPlugin()
{
  wsdebug(("> AxMenuConfigPlugin::~AxMenuConfigPlugin()"));

  myPlugin->SetupMenuActionFinished();

  wsdebug(("< AxMenuConfigPlugin::~AxMenuConfigPlugin()"));
} // AxMenuConfigPlugin::~AxMenuConfigPlugin()

#define DEBUG_PROCESS_KEY 0

//-------------------------------------------------------------------------
//     AxMenuConfigPlugin::ProcessKey()
//-------------------------------------------------------------------------
eOSState AxMenuConfigPlugin::ProcessKey(eKeys theKey)
{
#if DEBUG_PROCESS_KEY
  if (theKey != kNone)
  {
    wsdebug(("> AxMenuConfigPlugin::ProcessKey() Key: %-10s  Cur: %3d  HasSub: %d  parent processing..."
           , cKey::ToString(theKey)
           , Current()
           , HasSubMenu()
           ));
  } // if
#endif

  bool fHasSubMenu = HasSubMenu();
  eOSState aState = PARENT::ProcessKey(theKey);

#if DEBUG_PROCESS_KEY
  if (theKey != kNone)
  {
    wsdebug(("  AxMenuConfigPlugin::ProcessKey() Key: %-10s  Cur: %3d  HasSub: %d  State: %-10s  "
           , cKey::ToString(theKey)
           , Current()
           , HasSubMenu()
           , AxVdrTools::getOSStateStr(aState)
           ));
  } // if
#endif

  if ( fHasSubMenu && !HasSubMenu())
  {
    // submenu has disappeared
    wsdebug(("  AxMenuConfigPlugin::ProcessKey() submenu disappeared, MailBoxSetup: %p  fCodeOk: %d"
           , myLockMailBoxSetup
           , myLockCodeIsOk
           ));
    // submenu has disappeared -> edit mailbox setup if access code ok
    if (myLockMailBoxSetup && myLockCodeIsOk)
    {
      switch (myLockAction)
      {
        case ACT_EDIT:
        {
          myLockAction = ACT_NONE;
          cOsdMenu *anOsdMenu = new AxMenuConfigMailBox(&myNewSetup.PluginSettings, myLockMailBoxSetup);
          myLockMailBoxSetup = 0;
          return AddSubMenu(anOsdMenu);
        }
        case ACT_DELETE:
        {
          myLockAction = ACT_NONE;
          char szMsg[128];
          sprintf( szMsg, tr("Do you really want to delete account %s?"), myLockMailBoxSetup->AccountName);

          if (Interface->Confirm(szMsg))
          {
            myNewSetup.Accounts.remove(myLockMailBoxSetup);
            delete myLockMailBoxSetup;
            myLockMailBoxSetup = 0;
            Del(Current());
            Display();
          } // if
          return osContinue;
        }
        default:
        {
          myLockAction = ACT_NONE;
          break;
        }
      } // switch
    } // if
  } // if

  if (aState != osUnknown && fHasSubMenu)
  {
#if DEBUG_PROCESS_KEY
    if (theKey != kNone)
    {
      wsdebug(("< AxMenuConfigPlugin::ProcessKey() Key: %-10s  Cur: %3d  HasSub: %d  State: %-10s  already handled"
            , cKey::ToString(theKey)
            , Current()
            , HasSubMenu()
            , AxVdrTools::getOSStateStr(aState)
            ));
    } // if
#endif
    return aState;
  } // if

  //----- select action... ----------------------------------------------------
  switch (theKey)
  {
    case kUp    :
    case kDown  :
    case kLeft  :
    case kRight :
    {
      setButtons();
      break;
    }

    //----- Edit -----
    case kRed   :
    {
      aState = osContinue;

      if (Current() == 0)
      {
        cOsdMenu *cOsdMenu = new AxMenuConfigCommon(&myNewSetup.PluginSettings);
        aState = AddSubMenu(cOsdMenu);
      }
      else
      {
        AxMailBoxSetupItem *aMBItem = dynamic_cast<AxMailBoxSetupItem *>(Get(Current()));
        if (aMBItem)
        {
          cOsdMenu *anOsdMenu = 0;

          if ( ( aMBItem->getMBSetup()->AccessMode == Ax::Mail::MailBoxSetup::AM_SETUP_READ
              || aMBItem->getMBSetup()->AccessMode == Ax::Mail::MailBoxSetup::AM_SETUP
               )
            && strlen(aMBItem->getMBSetup()->AccessCode) > 0)
          {
            myLockCodeIsOk = false;
            anOsdMenu = new AxMenuCode( aMBItem->getMBSetup()->AccessCode
                                      , sizeof(aMBItem->getMBSetup()->AccessCode) - 1
                                      , myLockCodeIsOk
                                      );
            myLockMailBoxSetup = aMBItem->getMBSetup();
            myLockAction       = ACT_EDIT;
          }
          else
          {
            anOsdMenu = new AxMenuConfigMailBox(&myNewSetup.PluginSettings, aMBItem->getMBSetup());
          } // if
          aState = AddSubMenu(anOsdMenu);
        } // if
      } // if
      break;
    }

    //----- New ------
    case kGreen :
    {
      Mail::MailBoxSetup *aMBSetup = new Mail::MailBoxSetup();
      strcpy(aMBSetup->AccountName, tr("new account"));
      myNewSetup.Accounts.push_back(aMBSetup);
      Add(new AxMailBoxSetupItem(aMBSetup));

      cOsdMenu *anOsdMenu = new AxMenuConfigMailBox(&myNewSetup.PluginSettings, aMBSetup);
      aState = AddSubMenu(anOsdMenu);
      break;
    }

    //----- Delete -----
    case kYellow:
    {
      aState = osContinue;
      AxMailBoxSetupItem *aMBItem = dynamic_cast<AxMailBoxSetupItem *>(Get(Current()));
      if (aMBItem)
      {
        Mail::MailBoxSetup *aMBSetup = aMBItem->getMBSetup();

        if ( ( aMBItem->getMBSetup()->AccessMode == Ax::Mail::MailBoxSetup::AM_SETUP_READ
            || aMBItem->getMBSetup()->AccessMode == Ax::Mail::MailBoxSetup::AM_SETUP
              )
          && strlen(aMBItem->getMBSetup()->AccessCode) > 0
            )
        {
          cOsdMenu *anOsdMenu = new AxMenuCode( aMBItem->getMBSetup()->AccessCode
                                              , sizeof(aMBItem->getMBSetup()->AccessCode) - 1
                                              , myLockCodeIsOk
                                              );
          myLockMailBoxSetup = aMBItem->getMBSetup();
          myLockAction       = ACT_DELETE;
          aState = AddSubMenu(anOsdMenu);
        }
        else
        {
          char szMsg[128];
          sprintf( szMsg, tr("Do you really want to delete account %s?"), aMBSetup->AccountName);

          if (Interface->Confirm(szMsg))
          {
            myNewSetup.Accounts.remove(aMBSetup);
            delete aMBSetup;
            Del(Current());
            Display();
          } // if
        } // if
      } // if
      break;
    }

    //----- ??? ------
    case kBlue:
    {
      break;
    }

    //----- default -----
    default     :
    {
//      aState = osUnknown;
      break;
    }
  } // switch

#if DEBUG_PROCESS_KEY
  if (theKey != kNone)
  {
    wsdebug(("< AxMenuConfigPlugin::ProcessKey() Key: %-10s  Cur: %3d  HasSub: %d  State: %-10s  "
          , cKey::ToString(theKey)
          , Current()
          , HasSubMenu()
          , AxVdrTools::getOSStateStr(aState)
          ));
  } // if
#endif
  return aState;
} // AxMenuConfigPlugin::ProcessKey()

//-------------------------------------------------------------------------
//     AxMenuConfigPlugin::setButtons()
//-------------------------------------------------------------------------
void AxMenuConfigPlugin::setButtons(int theButtonPageNum)
{
  cOsdItem           *anItem  = Get(Current());
  AxMailBoxSetupItem *aMBItem = dynamic_cast<AxMailBoxSetupItem *>(anItem);

  const char *aButton1Text = aMBItem  || Current() == 0 ? tr("Edit"  ) : 0;
  const char *aButton2Text =                              tr("New"   )    ;
  const char *aButton3Text = aMBItem                    ? tr("Delete") : 0;
  const char *aButton4Text =                                             0;

  SetHelp(aButton1Text, aButton2Text, aButton3Text, aButton4Text);

//  Display();
} // AxMenuConfigPlugin::setButtons()

//-------------------------------------------------------------------------
//     AxMenuConfigPlugin::AddSeparator()
//-------------------------------------------------------------------------
void AxMenuConfigPlugin::AddSeparator(const char *Title)
{
  char *aBuffer = NULL;

  asprintf( &aBuffer
          , "--- %s ----------------------------------------------------------------"
          , Title );

  cOsdItem *anItem = new cOsdItem(aBuffer);
  free(aBuffer);
  anItem->SetSelectable(false);

   Add(anItem);
} // AxMenuConfigPlugin::AddSeparator()

//-------------------------------------------------------------------------
//     AxMenuConfigPlugin::Store()
//-------------------------------------------------------------------------
void AxMenuConfigPlugin::Store(void)
{
  wsdebug(("> AxMenuConfigPlugin::Store()"));

  *myOldSetup = myNewSetup;

  // the settings are loaded in AxPluginMailBox::setupParse()
  SetupStore("BGCheckDelay"  , myOldSetup->PluginSettings.BGCheckDelay    );
  SetupStore("DebugCClient"  , myOldSetup->PluginSettings.DebugCClient    );
#if ALEX_NOPORT
  SetupStore("MBV_Font"      , myOldSetup->PluginSettings.MBV_Font        );
  SetupStore("MLV_Font"      , myOldSetup->PluginSettings.MLV_Font        );
#endif
  SetupStore("MLV_SortOrder" , myOldSetup->PluginSettings.MLV_SortOrder   );
  SetupStore("MLV_MaxMails"  , myOldSetup->PluginSettings.MLV_MaxMails    );
#if ALEX_NOPORT
  SetupStore("MV_HeadFont"   , myOldSetup->PluginSettings.MV_HeadFont     );
  SetupStore("MV_BodyFont"   , myOldSetup->PluginSettings.MV_BodyFont     );
  SetupStore("MV_JumpSize"   , myOldSetup->PluginSettings.MV_JumpSize     );
#endif
  SetupStore("MV_ViewMode"   , myOldSetup->PluginSettings.MV_ViewMode     );

  if (!myOldSetup->saveAccounts())
  {
    Skins.Message(mtError, tr("Unable to write to config-file!"));
  } // if

  wsdebug(("< AxMenuConfigPlugin::Store()"));
} // AxMenuConfigPlugin::Store()

