//-----------------------------------------------------------------------------
/*
 * Description: This file contains the class AxPluginSwitchOSDPos
 *
 * 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:   04.11.2004
 *
 * Last modfied:
 *   $Author: alex $
 *   $Date: 2006-03-11 18:05:26 +0100 (Sa, 11 Mär 2006) $
 *   $Revision: 27 $
 */
//-----------------------------------------------------------------------------

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

//----- swap-workaround -------------------------------------------------------
#include "AxPluginGlobals.h"

//----- C++ -------------------------------------------------------------------
//----- C ---------------------------------------------------------------------
//----- AxLib -----------------------------------------------------------------
//----- vdr -------------------------------------------------------------------
#include <vdr/plugin.h>
#include <vdr/skins.h>

//----- local -----------------------------------------------------------------
#include "AxPluginSwitchOSDPos.h"
#include "AxSwitchOSDPosServiceTypes.h"
#include "AxMenu.h"
#include "i18n.h"

//=============================================================================
//     defines
//=============================================================================
#define FREENULL(p) (free(p), p = NULL)

//=============================================================================
//     static
//=============================================================================
static const char *VERSION        = "0.1.0";
static const char *DESCRIPTION    = "switch OSD-positions/sizes";

//=============================================================================
//     class AxPluginSwitchOSDPos
//=============================================================================

//-----------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::AxPluginSwitchOSDPos()
//-----------------------------------------------------------------------------
AxPluginSwitchOSDPos::AxPluginSwitchOSDPos(void)
                    : myMainMenuEntry( 0)
{
  // Initialize any member variables here.
  // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
  // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
} // AxPluginSwitchOSDPos::AxPluginSwitchOSDPos()

//-----------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::~AxPluginSwitchOSDPos()
//-----------------------------------------------------------------------------
AxPluginSwitchOSDPos::~AxPluginSwitchOSDPos()
{
  // Clean up after yourself!
  FREENULL(myMainMenuEntry);
} // AxPluginSwitchOSDPos::~AxPluginSwitchOSDPos()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Version()
//-------------------------------------------------------------------------
const char *AxPluginSwitchOSDPos::Version(void)
{
  return VERSION;
} // AxPluginSwitchOSDPos::Version()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Description()
//-------------------------------------------------------------------------
const char *AxPluginSwitchOSDPos::Description(void)
{
  return tr(DESCRIPTION);
} // AxPluginSwitchOSDPos::Description()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::CommandLineHelp()
//-------------------------------------------------------------------------
const char *AxPluginSwitchOSDPos::CommandLineHelp(void)
{
  // Return a string that describes all known command line options.
  return NULL;
} // AxPluginSwitchOSDPos::CommandLineHelp()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::ProcessArgs()
//-------------------------------------------------------------------------
bool AxPluginSwitchOSDPos::ProcessArgs(int argc, char *argv[])
{
  // Implement command line argument processing here if applicable.
  return true;
} // AxPluginSwitchOSDPos::ProcessArgs()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Initialize()
//-------------------------------------------------------------------------
bool AxPluginSwitchOSDPos::Initialize(void)
{
  // Initialize any background activities the plugin shall perform.

  // load the presets
  if (mySetup.loadPresets(cPlugin::ConfigDirectory(Name())))
  {
    if (mySetup.Settings.ActivateOnStart)
    {
      // guess which present is currently active
      mySetup.activatePreset(0, false, false);
    }
    else
    {
      // guess which present is currently active
      mySetup.guessActive();
    } // if
  } // if

  return true;
} // AxPluginSwitchOSDPos::Initialize()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Start()
//-------------------------------------------------------------------------
bool AxPluginSwitchOSDPos::Start(void)
{
  // Start any background activities the plugin shall perform.

  // register i18n phrases
  RegisterI18n(Phrases);

  return true;
} // AxPluginSwitchOSDPos::Start()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Stop()
//-------------------------------------------------------------------------
void AxPluginSwitchOSDPos::Stop(void)
{
  // Stop any background activities the plugin shall perform.
  mySetup.Settings.storeSetup(this);
} // AxPluginSwitchOSDPos::Stop()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Housekeeping()
//-------------------------------------------------------------------------
void AxPluginSwitchOSDPos::Housekeeping(void)
{
  // Perform any cleanup or other regular tasks.
} // AxPluginSwitchOSDPos::Housekeeping()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::MainMenuEntry()
//-------------------------------------------------------------------------
const char *AxPluginSwitchOSDPos::MainMenuEntry(void)
{
  FREENULL(myMainMenuEntry);

  if (!mySetup.Settings.HideMainMenuEntry)
  {
    if (mySetup.Settings.MainMenuAction)
    {
      asprintf( &myMainMenuEntry
              , "%s"
              , tr("SwitchOSDPos")
              );
    }
    else
    {
      int aPAct  = mySetup.guessActive();
      int aPNext = mySetup.getNext();

      if (aPAct >= 0 && aPNext >= 0 && aPAct != aPNext)
      {
        asprintf( &myMainMenuEntry
                , "%s: %s -> %s"
                , tr("SwitchOSDPos")
                , mySetup.Presets[aPAct ].Name.c_str()
                , mySetup.Presets[aPNext].Name.c_str()
                );
      }
      else if (aPNext >= 0)
      {
        asprintf( &myMainMenuEntry
                , "%s: %s"
                , tr("SwitchOSDPos")
                , mySetup.Presets[aPNext].Name.c_str()
                );
      }
      else if (aPAct >= 0)
      {
        asprintf( &myMainMenuEntry
                , "%s: %s"
                , tr("SwitchOSDPos")
                , mySetup.Presets[aPAct].Name.c_str()
                );
      }
      else
      {
        asprintf( &myMainMenuEntry
                , "%s: %s"
                , tr("SwitchOSDPos")
                , tr("no presets")
                );
      } // if
    } // if
  } // if

  return myMainMenuEntry;
} // AxPluginSwitchOSDPos::MainMenuEntry()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::MainMenuAction()
//-------------------------------------------------------------------------
cOsdObject *AxPluginSwitchOSDPos::MainMenuAction(void)
{
  cOsdObject *anOSDObject = 0;
  // Perform the action when selected from the main VDR menu.
  if (mySetup.Presets.size() > 0)
  {
    if (mySetup.Settings.MainMenuAction)
    {
      anOSDObject = new AxMenuSelect(this);
    }
    else
    {
      mySetup.activateNext(mySetup.Settings.ShowStatusMsg, true);
    } // if
  }
  else
  {
    esyslog("%s: no presets defined!", Name());
    Skins.Message(mtWarning, tr("no presets defined"));
  } // if

  return anOSDObject;
} // AxPluginSwitchOSDPos::MainMenuAction()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::SetupMenu()
//-------------------------------------------------------------------------
cMenuSetupPage *AxPluginSwitchOSDPos::SetupMenu(void)
{
  // Return a setup menu in case the plugin supports one.
  return new AxMenuSetup(this);
} // AxPluginSwitchOSDPos::SetupMenu()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::SetupParse()
//-------------------------------------------------------------------------
bool AxPluginSwitchOSDPos::SetupParse(const char *Name, const char *Value)
{
  return mySetup.Settings.parseSetup(Name, Value);
} // AxPluginSwitchOSDPos::SetupParse()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::Service()
//-------------------------------------------------------------------------
bool AxPluginSwitchOSDPos::Service(const char *Id, void *Data)
{
  bool fHandled = true;

  if (strcmp(Id, SwitchOSDPos_ActivatePreset_v1_0_NAME) == 0)
  {
    //---- SwitchOSDPos_ActivatePreset_v1_0 -------------------------------
    if (Data != 0)
    {
      SwitchOSDPos_ActivatePreset_v1_0 *anArg = (SwitchOSDPos_ActivatePreset_v1_0 *)Data;

      if (*anArg->Name != 0 && strlen(*anArg->Name) > 0)
      {
        int i = mySetup.findPreset(std::string(*anArg->Name));
        if (i >= 0)
        {
          if (mySetup.activatePreset(i, false, false) == i)
          {
            isyslog("switchosdpos: preset '%s' activated", *anArg->Name);
            anArg->ErrorCode = 0;
          }
          else
          {
            isyslog("switchosdpos: preset '%s' not valid", *anArg->Name);
            anArg->ErrorCode = 2;
          }
        }
        else
        {
          isyslog("switchosdpos: preset '%s' not found", *anArg->Name);
          anArg->ErrorCode = 1;
        } // if
      }
      else
      {
        anArg->ErrorCode = 0;
      } // if

      int i = mySetup.guessActive();
      if (i >= 0)
      {
        anArg->Name = cString(mySetup.Presets[i].Name.c_str());
      }
      else
      {
        anArg->Name = cString();
      } // if
    } // if
  }
  else if (strcmp(Id, SwitchOSDPos_QueryPresets_v1_0_NAME) == 0)
  {
    //---- SwitchOSDPos_QueryPresets_v1_0 -------------------------------
    if (Data != 0)
    {
      SwitchOSDPos_QueryPresets_v1_0 *anArg = (SwitchOSDPos_QueryPresets_v1_0 *)Data;
      std::string aStr;

      for (AxOSDPresetCltn::const_iterator anIter  = mySetup.Presets.begin();
                                           anIter != mySetup.Presets.end();
                                         ++anIter)
      {
        aStr += (*anIter).Name + std::string("\n");
      } // for

      if (aStr.length() > 0)
      {
        anArg->Names = cString(aStr.c_str());
      }
      else
      {
        anArg->Names = cString();
      } // if
    } // if
  }
  else
  {
    fHandled = false;
  } // if

  return fHandled;
} // AxPluginSwitchOSDPos::Service()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::SVDRPHelpPages()
//-------------------------------------------------------------------------
const char **AxPluginSwitchOSDPos::SVDRPHelpPages(void)
{
  // Return help text for SVDRP commands this plugin implements

  static const char *HelpPages[] =
  {
    "LSTP\n"
    "    List all available presets.\n"
    "    reply codes:\n"
    "    900: for the list of presets\n"
    "    901: if no preset ist defined\n"
  ,
    "SETP [name]\n"
    "    Activates the preset with the given name.\n"
    "    Without a given name (or after a successfully activating the\n"
    "    given preset) it returns the name of the current preset.\n"
    "    Note: If the current OSD-Settings were modified by VDRs\n"
    "    own setup menu ant therefore can't be found within the\n"
    "    preset this command returns 901.\n"
    "    Note: no messages are displayed on the screen!\n"
    "    reply codes:\n"
    "    900: preset activated\n"
    "    901: preset not found\n"
    "    902: name of the active preset\n"
    "    903: no preset is active\n"
  ,
    NULL
  };

  return HelpPages;
} // AxPluginSwitchOSDPos::SVDRPHelpPages()

//-------------------------------------------------------------------------
//     AxPluginSwitchOSDPos::SVDRPCommand()
//-------------------------------------------------------------------------
cString AxPluginSwitchOSDPos::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
{
  cString aRetStr = NULL;

  if (strcasecmp(Command, "LSTP") == 0)
  {
    if (mySetup.Presets.size() > 0)
    {
      std::string aStr;
      for (AxOSDPresetCltn::const_iterator anIter  = mySetup.Presets.begin();
                                           anIter != mySetup.Presets.end();
                                         ++anIter)
      {
        aStr += (*anIter).Name + std::string("\n");
      } // for

      ReplyCode = 900;
      aRetStr = cString(aStr.c_str());
    }
    else
    {
      ReplyCode = 901;
      aRetStr = "no presets defined";
    } // if
  }
  else if (strcasecmp(Command, "SETP") == 0)
  {
    if (*Option)
    {
      int i = mySetup.findPreset(std::string(Option));
      if (i >= 0)
      {
        if (mySetup.activatePreset(i, false, false) == i)
        {
          aRetStr = cString("%s activated", mySetup.Presets[i].Name.c_str());
          ReplyCode = 900;
        }
        else
        {
          isyslog("switchosdpos: preset '%s' not valid", Option);
          aRetStr = cString("%s not valid", Option);
          ReplyCode = 901;
        }
      }
      else
      {
        isyslog("switchosdpos: preset '%s' not found", Option);
        aRetStr = cString("%s not found", Option);
        ReplyCode = 901;
      }
    }
    else
    {
      int i = mySetup.guessActive();

      if (i >= 0)
      {
        ReplyCode = 902;
        aRetStr = cString(mySetup.Presets[i].Name.c_str());
      }
      else
      {
        ReplyCode = 903;
        aRetStr = "no preset active";
      } // if
    } // if
  } // if

  return aRetStr;
} // AxPluginSwitchOSDPos::SVDRPCommand()

//-------------------------------------------------------------------------
//     don't touch this
//-------------------------------------------------------------------------
VDRPLUGINCREATOR(AxPluginSwitchOSDPos); // Don't touch this!
