

#include "setup.h"
#include "extb_osd_menu.h"




class cLEDItem
: public cOsdItem
, public cLircPtr 
{
protected:
  int min_item;
  int max_item;
  static const char *reset_cmd;
  static const char *set_cmd;
  static const char *toggle_cmd;
  static const char *flash_cmd;
public:
  cLEDItem(cLirc * pLirc, const char *name, int _min_item, int _max_item)
  :cLircPtr(pLirc) {
    min_item = _min_item;
    max_item = _max_item;
    SetText(name);
  } 
  
  virtual eOSState ProcessKey(eKeys Key);
};

const char *cLEDItem::reset_cmd  = "R_LD%d";
const char *cLEDItem::set_cmd    = "S_LD%d";
const char *cLEDItem::toggle_cmd = "T_LD%d";
const char *cLEDItem::flash_cmd  = "B_LD%d";

eOSState cLEDItem::ProcessKey(eKeys nKey)
{
  char sz[16];
  const char *cmd = NULL;
  eOSState state = cOsdItem::ProcessKey(nKey);
  
  switch(nKey) {
  case kRed:    cmd = reset_cmd;  break;
  case kGreen:  cmd = set_cmd;    break;
  case kYellow: cmd = toggle_cmd; break;
  case kBlue:   cmd = flash_cmd;  break;
  default:                        break;
	}

  if(cmd) {
    for (int i = min_item; i <= max_item; i++) {
		    snprintf(sz, sizeof(sz), cmd, i);
		    m_pLirc->send(sz);
		}
	}
  return (state);
}

class cExtOutItem
 : public cOsdItem
 , public cLircPtr 
{
protected:
  int min_item;
  int max_item;
  static const char *reset_cmd;
  static const char *set_cmd;
  static const char *toggle_cmd;
public:
  cExtOutItem(cLirc * pLirc,const char *name, int _min_item, int _max_item)
  : cLircPtr(pLirc) {
    min_item = _min_item;
    max_item = _max_item;
    SetText(name);
  } 
  virtual eOSState ProcessKey(eKeys Key);
};

const char *cExtOutItem::reset_cmd  = "R_OUT%d";
const char *cExtOutItem::set_cmd    = "S_OUT%d";
const char *cExtOutItem::toggle_cmd = "T_OUT%d";

eOSState cExtOutItem::ProcessKey(eKeys nKey)
{
  char sz[16];
  const char *cmd = NULL;
  eOSState state = cOsdItem::ProcessKey(nKey);
  
  switch(nKey) {
  case kRed:    cmd = reset_cmd;  break;
  case kGreen:  cmd = set_cmd;    break;
  case kYellow: cmd = toggle_cmd; break;
  default:                        break;
  }

  if(cmd) {
    for (int i = min_item; i <= max_item; i++) {
		    snprintf(sz, sizeof(sz), cmd, i);
		    m_pLirc->send(sz);
		}
	}
  return (state);
}

class cStdOnOffItem
 : public cOsdItem
 , public cLircPtr
{
protected:
  char cmd_on[10];
  char cmd_off[10];
public:
  cStdOnOffItem(cLirc * pLirc, const char *name, const char *_cmd_on, const char *_cmd_off)
  : cLircPtr(pLirc) {
    strncpy(cmd_on,  _cmd_on,  sizeof(cmd_on));
    strncpy(cmd_off, _cmd_off, sizeof(cmd_off));
    SetText(name);
  } 
  virtual eOSState ProcessKey(eKeys Key);
};

eOSState cStdOnOffItem::ProcessKey(eKeys nKey)
{
  const char *cmd = NULL;
  eOSState state = cOsdItem::ProcessKey(nKey);
  
  switch(nKey) {
  case kRed:    cmd = cmd_off;    break;
  case kGreen:  cmd = cmd_on;     break;
  default:                        break;
  }

  if(cmd) {
    m_pLirc->send(cmd);
	}
  return (state);
}

class cMacroItem
 : public cOsdItem
 , public cLircPtr {
protected:
  char cmd[10];
  bool reset_cmd_after_key;
  time_t reset_cmd_time;
public:
  cMacroItem(cLirc * pLirc, const char *name,const char *_cmd)
   : cLircPtr(pLirc) {
    strncpy(cmd, _cmd, sizeof(cmd));
    reset_cmd_after_key = false;
    reset_cmd_time = (time_t) - 1;
    SetText(name);
  } 
  virtual eOSState ProcessKey(eKeys Key);
};

eOSState cMacroItem::ProcessKey(eKeys nKey)
{
  eOSState state = cOsdItem::ProcessKey(nKey);

  if(reset_cmd_after_key) {
    time_t now = time(NULL);
    if(now - reset_cmd_time > 15) {
		    reset_cmd_after_key = false;
		    m_pLirc->send("M1");
		}
	}

  switch(nKey) {
  case kRed:    
  case kGreen:    
  case kOk:    {
    m_pLirc->send(cmd);
    if(kRed == nKey) {
        reset_cmd_after_key = true;
        reset_cmd_time = time(NULL);
    }
    break;    
  }
  case kYellow: m_pLirc->send("M1");break;
  default:                          break;
  }

  return (state);
}

class cLEDMenu
 : public cOsdMenu {
public:
  cLEDMenu(cLirc * pLirc);
};

cLEDMenu::cLEDMenu(cLirc * pLirc)
: cOsdMenu(tr("Status LEDs"))
{
  char sz[64];
  SetHasHotkeys();
  
  for(unsigned int n=1;n<LED_CNT+1;++n)   {
     snprintf(sz,memberof(sz),"%s #%d",tr("Status LED"),n);
     Add(new cLEDItem(pLirc,hk(sz), n, n));
  }

  snprintf(sz,memberof(sz),"%s #%d-%d",tr("Status LED"),1,LED_CNT);
  Add(new cLEDItem(pLirc,hk(sz), 1, LED_CNT));

  SetHelp(tr("off"), tr("on"), tr("toggle"), tr("flash"));
}

class cExtOutMenu
 : public cOsdMenu {
public:
  cExtOutMenu(cLirc * pLirc);
};

cExtOutMenu::cExtOutMenu(cLirc * pLirc)
: cOsdMenu(tr("External Outputs"))
{
  char sz[64];
  SetHasHotkeys();
  
  for(unsigned int n=1;n<=OUT_CNT;++n)   {
     snprintf(sz,memberof(sz),"%s #%d",tr("External Output"),n);
     Add(new cExtOutItem(pLirc,hk(sz), n, n));
  }

  snprintf(sz,memberof(sz),"%s #%d-%d",tr("External Output"),1,OUT_CNT);
  Add(new cExtOutItem(pLirc,hk(sz), 1, OUT_CNT));

  SetHelp(tr("off"), tr("on"), tr("toggle"), NULL);
}

class cMacroMenu
 : public cOsdMenu {
public:
  cMacroMenu(cLirc * pLirc);
};

cMacroMenu::cMacroMenu(cLirc * pLirc)
 : cOsdMenu(tr("Macros"))
{
  static const char* szMacroCmd[] = 
  { "M1","M2","M3","M4",
    "M5","M6","M7","M8",
    "M9","M10"    };
  char sz[64];

  SetHasHotkeys();

  for(unsigned int n=0;n<memberof(szMacroCmd);++n)   {
     snprintf(sz,memberof(sz),"%s #%d",tr("Macro"),n+1);
     Add(new cMacroItem(pLirc, hk(sz), szMacroCmd[n]));
  }
  
  SetHelp(tr("test 15s"), tr("send"), tr("reset (M1)"), NULL);
}



class cLCDMenu
: public cOsdMenu {
public:
  cLCDMenu(cLirc * pLirc);
};

cLCDMenu::cLCDMenu(cLirc * pLirc)
 : cOsdMenu(tr("LC-Display & Backlight"))
{
    SetHasHotkeys();

    Add(new cStdOnOffItem(pLirc,hk(tr("LCD contract voltage")),"S_LCD",   "R_LCD"));
    Add(new cStdOnOffItem(pLirc,hk(tr("LCD backlight")),       "S_LCD_BL","R_LCD_BL"));

    SetHelp(tr("off"), tr("on"), NULL, NULL);
}


class cVideoMenu
: public cOsdMenu {
public:
    cVideoMenu(cLirc * pLirc);
};

cVideoMenu::cVideoMenu(cLirc * pLirc)
: cOsdMenu(tr("Video"))
{
    SetHasHotkeys();

    Add(new cMacroItem(pLirc, hk(tr("videosource DVB")),            "S_DVB"));
    Add(new cMacroItem(pLirc, hk(tr("videosource VGA")),            "S_VGA"));
    Add(new cMacroItem(pLirc, hk(tr("videosource AUX")),            "S_AUX"));
    Add(new cMacroItem(pLirc, hk(tr("videosource off")),            "R_VID_ALL"));
    Add(new cMacroItem(pLirc, hk(tr("videosource DVB/VGA toggle")), "T_DVB_VGA"));
    Add(new cMacroItem(pLirc, hk(tr("videosource DVB/AUX toggle")), "T_DVB_AUX"));
    Add(new cMacroItem(pLirc, hk(tr("videosource VGA/AUX toggle")), "T_VGA_AUX"));
    Add(new cMacroItem(pLirc, hk(tr("switch Scart pin #8 to 6V (16:9)")), "S_SC8_6V"));
    Add(new cMacroItem(pLirc, hk(tr("switch Scart pin #8 to 12V (AV-Mode)")), "R_SC8_6V"));

    SetHelp(tr("test 15s"), tr("send"), tr("reset (M1)"), NULL );
}

class cAudioMenu
: public cOsdMenu {
public:
  cAudioMenu(cLirc * pLirc);
};

cAudioMenu::cAudioMenu(cLirc * pLirc)
 : cOsdMenu(tr("Audio"))
{
    SetHasHotkeys();

    Add(new cMacroItem(pLirc, hk(tr("analog audio off")), "S_ANA"));
    Add(new cMacroItem(pLirc, hk(tr("analog audio on")), "R_ANA"));
    Add(new cMacroItem(pLirc, hk(tr("analog audio toggle")), "T_ANA"));
    Add(new cMacroItem(pLirc, hk(tr("digital audio on")), "S_DIA"));
    Add(new cMacroItem(pLirc, hk(tr("digital audio off")), "R_DIA"));
    Add(new cMacroItem(pLirc, hk(tr("digital audio toggle")), "T_DIA"));
    Add(new cMacroItem(pLirc, hk(tr("analog and digital audio on")), "S_ANDIA"));
    Add(new cMacroItem(pLirc, hk(tr("analog and digital audio off")), "R_ANDIA"));
    Add(new cMacroItem(pLirc, hk(tr("analog and digital audio toggle")),"T_ANDIA"));

    SetHelp(tr("test 15s"), tr("send"), tr("reset (M1)"), NULL );
}

cExtBOsdMenu::cExtBOsdMenu(cLirc * pLirc)
: cOsdMenu(tr("Extension board"))
, cLircPtr(pLirc)
{
    SetHasHotkeys();

    Add(new cOsdItem(hk(tr("Status LEDs")), osUser1));
    Add(new cOsdItem(hk(tr("LC-Display & Backlight")), osUser2));
    Add(new cOsdItem(hk(tr("External Outputs")), osUser3));
    Add(new cOsdItem(hk(tr("Macros")), osUser4));
    Add(new cOsdItem(hk(tr("Audio")), osUser5));
    Add(new cOsdItem(hk(tr("Video")), osUser6));

    SetHelp(NULL, NULL, NULL, NULL);
  
    Display();
}

cExtBOsdMenu::~cExtBOsdMenu()
{
}

eOSState cExtBOsdMenu::ProcessKey(eKeys nKey)
{
  eOSState state = cOsdMenu::ProcessKey(nKey);

  switch (state)
	{
	case osUser1: state = AddSubMenu(new cLEDMenu(m_pLirc));    break;
	case osUser2: state = AddSubMenu(new cLCDMenu(m_pLirc));    break;
	case osUser3: state = AddSubMenu(new cExtOutMenu(m_pLirc)); break;
	case osUser4: state = AddSubMenu(new cMacroMenu(m_pLirc));  break;
	case osUser5: state = AddSubMenu(new cAudioMenu(m_pLirc));  break;
	case osUser6: state = AddSubMenu(new cVideoMenu(m_pLirc));  break;

	case osContinue:
	    break;
	default:
    break;
	}

  if(!HasSubMenu())
    Display();

  return (state);
}
