
#include <stdio.h>

#include "extb_setup_menu.h"
#include "extb.h"


///////////////////////////////////////////////////////////////////////////////
/* Create a Setupmenu with all feature of a LED

e.g. Activate LEDx 
  -- if state          Canal with DPID
  -- or state          Playback with DTS
  -- or state          Playback with AC3
  -- or state          Never
  -- reverse results   no
*/
class cMenuWithIOFeature
: public cOsdMenu {
  /// reference to the original parameter
  cIOFeature& m_ioOriginal;
  /// Working parameter, changes would make on this
  cIOFeature m_ioTemp;
public:
  cMenuWithIOFeature(const char* szTitle,cIOFeature& x);
protected:
  virtual eOSState ProcessKey(eKeys nKey);
};

///////////////////////////////////////////////////////////////////////////////
/* Ctor for Menu with IO Features of 
*/
cMenuWithIOFeature::cMenuWithIOFeature(const char* szTitle,cIOFeature& x)
 : cOsdMenu(szTitle, 20,5)
 , m_ioOriginal(x)
 , m_ioTemp(x)
{
	Add(new cMenuEditStraItem(tr("Activate, if state"),
    &m_ioTemp.nState[0], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[1], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[2], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[3], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
		
  Add(new cMenuEditBoolItem(tr("reverse results"),        
    &m_ioTemp.nReverse,       tr("no"),tr("yes")));

  SetHelp(tr("save"), NULL, NULL, NULL);
}

///////////////////////////////////////////////////////////////////////////////
/*  Handle any Keystrokes on this menu
*/
eOSState cMenuWithIOFeature::ProcessKey(eKeys nKey)
{
  eOSState nState;
  nState = cOsdMenu::ProcessKey(nKey);
  if(nState == osUnknown 
      && (nKey == kOk || nKey == kRed )) {
    // Store edited Values
    m_ioOriginal = m_ioTemp;
    // goes only back to toplevel menu
    nState = osBack;
	}
  return nState;
}


class cMenuWithLEDFeature
: public cOsdMenu {
  /// reference to the original parameter
  cLEDFeature& m_ioOriginal;
  /// Working parameter, changes would make on this
  cLEDFeature m_ioTemp;
public:
  cMenuWithLEDFeature(const char* szTitle,cLEDFeature& x);
protected:
  virtual eOSState ProcessKey(eKeys nKey);
};

///////////////////////////////////////////////////////////////////////////////
/* Ctor for Menu with IO Features of 
*/
cMenuWithLEDFeature::cMenuWithLEDFeature(const char* szTitle,cLEDFeature& x)
 : cOsdMenu(szTitle, 20,5)
 , m_ioOriginal(x)
 , m_ioTemp(x)
{
	Add(new cMenuEditStraItem(tr("Activate, if state"),
    &m_ioTemp.nState[0], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[1], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[2], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
	Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nState[3], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
		
  Add(new cMenuEditBoolItem(tr("reverse results"),        
    &m_ioTemp.nReverse,       tr("no"),tr("yes")));

  Add(new cMenuEditStraItem(tr("Flashing, if state"),
    &m_ioTemp.nFlash[0], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
  Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nFlash[1], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
  Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nFlash[2], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));
  Add(new cMenuEditStraItem(tr("or state"),
    &m_ioTemp.nFlash[3], 
    memberof(cExtbSetup::m_szIOModes), cExtbSetup::m_szIOModes));

  Add(new cMenuEditBoolItem(tr("reverse results"),        
    &m_ioTemp.nFlashReverse,       tr("no"),tr("yes")));

  Add(new cMenuEditBoolItem(tr("flashing is important"),        
    &m_ioTemp.nFlashImportant,    tr("no"),tr("yes")));


  SetHelp(tr("save"), NULL, NULL, NULL);
}

eOSState cMenuWithLEDFeature::ProcessKey(eKeys nKey)
{
  eOSState nState;
  nState = cOsdMenu::ProcessKey(nKey);
  if(nState == osUnknown 
      && (nKey == kOk || nKey == kRed )) {
    // Store edited Values
    m_ioOriginal = m_ioTemp;
    // goes only back to toplevel menu
    nState = osBack;
	}
  return nState;
}


class cMenuWithLEDExtender
: public cOsdMenu {
  unsigned int m_nOffset;
  cExtbSetup& m_tempSetup;
public:
  cMenuWithLEDExtender(const char* szTitle,int nOff, cExtbSetup& tempSetup);
protected:
  virtual eOSState ProcessKey(eKeys nKey);
};

///////////////////////////////////////////////////////////////////////////////
/* Ctor for Menu with IO Features of 
*/
cMenuWithLEDExtender::cMenuWithLEDExtender(const char* szTitle,int nOff, cExtbSetup& tempSetup)
 : cOsdMenu(szTitle, 20,5)
 , m_nOffset(nOff)
 , m_tempSetup(tempSetup)
{
  char sz[256];

  for(unsigned int n=0;n<memberof(tempSetup.m_ioLEDMode)-nOff;++n)  {
      snprintf(sz,sizeof(sz),"%s #%d",tr("Configurate LED"),n + 1 + nOff);
      Add(new cOsdItem(sz, (eOSState)(osUser1 + n)));
    }		
  SetHelp(tr("save"), NULL, NULL, NULL);
}

///////////////////////////////////////////////////////////////////////////////
/*  Handle any Keystrokes on this menu
*/
eOSState cMenuWithLEDExtender::ProcessKey(eKeys nKey)
{
  eOSState nState;
  nState = cOsdMenu::ProcessKey(nKey);
  if(nState == osUnknown 
      && (nKey == kOk || nKey == kRed )) {
    // goes only back to toplevel menu
    nState = osBack;
	}
  if(nState >= osUser1 
    && nState < (eOSState)(osUser1 + (memberof(m_tempSetup.m_ioLEDMode) - m_nOffset)))
  {
    char sz[256];
    int n =  (nState - osUser1) + m_nOffset;
    snprintf(sz,sizeof(sz),"%s #%d",tr("Configurate LED"),n + 1);
    nState = AddSubMenu(new cMenuWithLEDFeature(sz,m_tempSetup.m_ioLEDMode[n]));
  }

  return nState;
}

///////////////////////////////////////////////////////////////////////////////
/* Create the Menu with the Pluginsetup
*/
cExtBMenuSetup::cExtBMenuSetup(cExtBoardIO*    pExt)
     //  : cOsdMenu(tr("Extension board"), 20, 5)
 : m_pExt(pExt)
 , m_tempSetup(theSetup)
 , m_nWaitForInit(0)
 , m_bShouldInitMenu(true)
{
  unsigned int n;

  SetStatus(tr("reading settings from controller, please wait"));

  gLircWatch->StartWatch();
  m_pExt->send("STATUS");

  m_nOldVideoModeDVB = 
    m_nVideoModeDVB = eRGB;
  m_nOldVideoModeVGA = 
    m_nVideoModeVGA = eRGB;
  m_nOldVideoModeAUX = 
    m_nVideoModeAUX = eRGB;

  m_nOldScartPin8Mode = 
     m_nScartPin8Mode = eF_SC8_PWR;
  m_nOldVideoSourceOnBoot =
     m_nVideoSourceOnBoot = eF_BOOT_VGA;   

  for(n=0;n<memberof(m_szVideoModesDVB);++n) 
    m_szVideoModesDVB[n] = NULL;
  
  for(n=0;n<memberof(m_szVideoModesAUX);++n) 
    m_szVideoModesAUX[n] = NULL;
  
  for(n=0;n<memberof(m_szVideoModesVGA);++n) 
    m_szVideoModesVGA[n] = NULL;
  
  for(n=0;n<memberof(m_szScartPin8Mode);++n) 
    m_szScartPin8Mode[n] = NULL;
  
  for(n=0;n<memberof(m_szVideoSourceOnBoot);++n) 
    m_szVideoSourceOnBoot[n] = NULL;
  
  m_tempSetup.LoadTranslatedStings();

  SetHelp(tr("save"), NULL, NULL, NULL); // Use only default keys, OK-> Store, Exit -> Back
}

///////////////////////////////////////////////////////////////////////////////
/* Dtor
*/
cExtBMenuSetup::~cExtBMenuSetup()
{
  unsigned int n;
  for(n=0;n<memberof(m_szVideoModesDVB);++n) 
    if(m_szVideoModesDVB[n]) 
      free(m_szVideoModesDVB[n]);
    
  for(n=0;n<memberof(m_szVideoModesAUX);++n)
    if(m_szVideoModesAUX[n]) 
      free(m_szVideoModesAUX[n]);
    
  for(n=0;n<memberof(m_szVideoModesVGA);++n)
    if(m_szVideoModesVGA[n]) 
      free(m_szVideoModesVGA[n]);
    
  for(n=0;n<memberof(m_szScartPin8Mode);++n)
    if(m_szScartPin8Mode[n]) 
      free(m_szScartPin8Mode[n]);
    
  for(n=0;n<memberof(m_szVideoSourceOnBoot);++n)
    if(m_szVideoSourceOnBoot[n]) 
      free(m_szVideoSourceOnBoot[n]);
}

///////////////////////////////////////////////////////////////////////////////
/* Translationtable LIRC-Code to Scart and Bootmode
*/
const cExtBMenuSetup::ScartBootMode cExtBMenuSetup::ScartBootModes[] = {
  //  ScartPin8Mode  VideoSourceOnBoot 
  {   eF_SC8_OFF,    eF_BOOT_OFF  },// SB0
  {   eF_SC8_PWR,    eF_BOOT_OFF  },// SB1
  {   eF_SC8_VDR,    eF_BOOT_OFF  },// SB2
  {  -1,            -1            },// don't use this line
  {   eF_SC8_OFF,    eF_BOOT_VGA  },// SB4
  {   eF_SC8_PWR,    eF_BOOT_VGA  },// SB5
  {   eF_SC8_VDR,    eF_BOOT_VGA  },// SB6
  {  -1,            -1            },// don't use this line
  {   eF_SC8_OFF,    eF_BOOT_AUX  },// SB8
  {   eF_SC8_PWR,    eF_BOOT_AUX  },// SB9
  {   eF_SC8_VDR,    eF_BOOT_AUX  },// SBa
};
             
///////////////////////////////////////////////////////////////////////////////
/*  Translationtable LIRC-Code to Videomode
*/
const cExtBMenuSetup::VideoMode cExtBMenuSetup::VideoModes[] = {
  //  DVB    VGA    AUX
  {   eSVID, eSVID, eSVID  },// V0
  {   eRGB,  eSVID, eSVID  },// V1
  {   eSVID, eRGB,  eSVID  },// V2
  {   eRGB,  eRGB,  eSVID  },// V3
  {   eSVID, eSVID, eRGB   },// V4
  {   eRGB,  eSVID, eRGB   },// V5
  {   eSVID, eRGB,  eRGB   },// V6
  {   eRGB,  eRGB,  eRGB   } // V7
};

///////////////////////////////////////////////////////////////////////////////
/*  Handle any Keystrokes on this menu, and use this as little thread with
    gLircWatch */ 
eOSState cExtBMenuSetup::ProcessKey(eKeys nKey)
{
  char sz[256];
  eOSState nState;

  nState = cMenuSetupPage::ProcessKey(nKey);
  if(nState == osUnknown && nKey == kRed) // Store Values and leave Menu
  {
    Store();
    nState = osBack;
  }

  if(!gLircWatch->WatchSuccess() 
    && m_nWaitForInit < 5 )
  {
    if(++m_nWaitForInit < 5)
    {
      strncpy(sz,tr("reading settings from controller, please wait"),sizeof(sz));
      for(int i=0; i < m_nWaitForInit; i++)
        strncat(sz, ".",sizeof(sz));
    
      SetStatus(sz);
    }
    else {
      SetStatus(tr("can't read settings from controller"));
    }
  }
  else if(m_bShouldInitMenu)
  {
    m_bShouldInitMenu = false;
    
    // Translate LIRC-Code to Videomode      
    unsigned int nV = gLircWatch->GetVideoModes();
    if(nV<memberof(VideoModes)) {
      m_nOldVideoModeDVB = 
        m_nVideoModeDVB = VideoModes[nV].nDVB;
      m_nOldVideoModeVGA = 
        m_nVideoModeVGA = VideoModes[nV].nVGA;
      m_nOldVideoModeAUX = 
        m_nVideoModeAUX = VideoModes[nV].nAUX;
    }
    
    // Translate LIRC-Code to Scart and Bootmode 
    unsigned int nSB = gLircWatch->GetScartBootModes();
    if(nSB<memberof(ScartBootModes) 
      && ScartBootModes[nSB].nScartPin8Mode != -1
      && ScartBootModes[nSB].nVideoSourceOnBoot != -1) {
        m_nOldScartPin8Mode = 
           m_nScartPin8Mode = ScartBootModes[nSB].nScartPin8Mode;
        m_nOldVideoSourceOnBoot =
           m_nVideoSourceOnBoot = ScartBootModes[nSB].nVideoSourceOnBoot;        
      }
      
    // assign read values from controller with current visble active mode => (X)
    asprintf(&m_szVideoModesDVB[eRGB],"%s%s",tr("RGB"),m_nVideoModeDVB==eRGB?" (X)":""); 
    asprintf(&m_szVideoModesVGA[eRGB],"%s%s",tr("RGB"),m_nVideoModeVGA==eRGB?" (X)":""); 
    asprintf(&m_szVideoModesAUX[eRGB],"%s%s",tr("RGB"),m_nVideoModeAUX==eRGB?" (X)":""); 
    
    asprintf(&m_szVideoModesDVB[eSVID],"%s%s",tr("S-Video/comp. sync"),  m_nVideoModeDVB==eSVID?" (X)":""); 
    asprintf(&m_szVideoModesVGA[eSVID],"%s%s",tr("S-Video/comp. sync"),  m_nVideoModeVGA==eSVID?" (X)":""); 
    asprintf(&m_szVideoModesAUX[eSVID],"%s%s",tr("S-Video/comp. sync"),  m_nVideoModeAUX==eSVID?" (X)":""); 
    
    asprintf(&m_szScartPin8Mode[eF_SC8_PWR],"%s%s",tr("Power on"),    m_nScartPin8Mode==eF_SC8_PWR?" (X)":""); 
    asprintf(&m_szScartPin8Mode[eF_SC8_VDR],"%s%s",tr("running VDR"), m_nScartPin8Mode==eF_SC8_VDR?" (X)":""); 
    asprintf(&m_szScartPin8Mode[eF_SC8_OFF],"%s%s",tr("never"),       m_nScartPin8Mode==eF_SC8_OFF?" (X)":""); 

    asprintf(&m_szVideoSourceOnBoot[eF_BOOT_VGA],"%s%s",tr("VGA"),    m_nVideoSourceOnBoot==eF_BOOT_VGA?" (X)":""); 
    asprintf(&m_szVideoSourceOnBoot[eF_BOOT_AUX],"%s%s",tr("AUX"),    m_nVideoSourceOnBoot==eF_BOOT_AUX?" (X)":""); 
    asprintf(&m_szVideoSourceOnBoot[eF_BOOT_OFF],"%s%s",tr("off"),    m_nVideoSourceOnBoot==eF_BOOT_OFF?" (X)":""); 
  
      
    // Create all menuentrys
    Add(new cMenuEditBoolItem(tr("Hide Mainmenu Entry"),        
      &m_tempSetup.m_bHideMainMenuEntry,tr("no"),tr("yes")));

    Add(new cMenuEditStraItem(tr("Deactivate on mute"),  
      &m_tempSetup.m_nMuteMode, 
      memberof(m_tempSetup.m_szMuteModes), 
      m_tempSetup.m_szMuteModes));



    unsigned int o = 0;
    unsigned int n;
    for(n=0;n<6;++n,++o) {
      snprintf(sz,sizeof(sz),"%s #%d",tr("Configurate LED"),n + 1);
      Add(new cOsdItem(sz, (eOSState)(osUser1 + o)));
    }	
    snprintf(sz,sizeof(sz),"%s #%d-#%d",tr("Configurate LED"),n + 1,memberof(theSetup.m_ioLEDMode));
    Add(new cOsdItem(sz, (eOSState)(osUser1 + o)));
    ++o; 
    for(unsigned int n=0;n<memberof(m_tempSetup.m_ioOutputMode);++n,++o) {
      snprintf(sz,sizeof(sz),tr("Configurate external output #%d"),n + 1);
      Add(new cOsdItem(sz, (eOSState)(osUser1 + o)));
    }	

    Add(new cMenuEditStraItem(tr("DVB mode"),              
      &m_nVideoModeDVB, 
      memberof(m_szVideoModesDVB), m_szVideoModesDVB));

    Add(new cMenuEditStraItem(tr("VGA mode"),              
      &m_nVideoModeVGA, 
      memberof(m_szVideoModesVGA), m_szVideoModesVGA));

    Add(new cMenuEditStraItem(tr("AUX mode"),              
      &m_nVideoModeAUX, 
      memberof(m_szVideoModesAUX), m_szVideoModesAUX));

    Add(new cMenuEditStraItem(tr("Enable scart pin #8 (AV-Mode)"),   
      &m_nScartPin8Mode, 
      memberof(m_szScartPin8Mode), m_szScartPin8Mode));

    Add(new cMenuEditStraItem(tr("Video source on boot"),  
      &m_nVideoSourceOnBoot, 
      memberof(m_szVideoSourceOnBoot), m_szVideoSourceOnBoot));

    static const char szAllowed[] = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_ " };

    Add(new cMenuEditStrItem (tr("Startup macrosequence"),                 
      m_tempSetup.m_szStartUp,sizeof(m_tempSetup.m_szStartUp), szAllowed));

    Add(new cMenuEditStrItem (tr("Shutdown macrosequence"),                 
      m_tempSetup.m_szShutDown,sizeof(m_tempSetup.m_szShutDown), szAllowed));

    SetStatus(NULL);

    Display();
  }
  else {
  
    if(nState >= osUser1 && nState <= osUser6)
    {
      int n = nState - osUser1;
      snprintf(sz,sizeof(sz),"%s #%d",tr("Configurate LED"),n + 1);
      nState = AddSubMenu(new cMenuWithLEDFeature(sz,m_tempSetup.m_ioLEDMode[n]));
    }
    else if(nState == osUser7)
    {  
      int n = nState - osUser1;
			snprintf(sz,sizeof(sz),"%s #%d-#%d",tr("Configurate LED"),n + 1,memberof(theSetup.m_ioLEDMode));
      nState = AddSubMenu(new cMenuWithLEDExtender(sz,n, m_tempSetup));    
    }
    else if(nState >= osUser8 && nState < (eOSState)(osUser8+memberof(m_tempSetup.m_ioOutputMode)))
    {  
      int n = nState - osUser8;
      snprintf(sz,sizeof(sz),tr("Configurate external output #%d"),n + 1);
      nState = AddSubMenu(new cMenuWithIOFeature(sz,m_tempSetup.m_ioOutputMode[n]));
    }
  	if(!HasSubMenu())
    	Display();  
	}
	return (nState);
}


///////////////////////////////////////////////////////////////////////////////
/* Store Profile on leave Setupmenu with OK
*/
void cExtBMenuSetup::Store()
{
  theSetup = m_tempSetup;

  SetupStore("HideMainMenuEntry", 		theSetup.m_bHideMainMenuEntry);
  SetupStore("MuteMode", 				      theSetup.m_nMuteMode);
  SetupStore("Startup",               theSetup.m_szStartUp);
  SetupStore("Shutdown",              theSetup.m_szShutDown);

  // store Setup for all LEDs
  char sz[16];//LEDMode1..LEDMode2... = 10,20
  char* sValue=NULL;
  for(unsigned int n=0;n<memberof(theSetup.m_ioLEDMode);++n) {
    snprintf(sz,sizeof(sz),"LEDMode%d",n + 1);  

	  for(unsigned int m=0;m<memberof(theSetup.m_ioLEDMode[0].nState);++m){
	   		if(theSetup.m_ioLEDMode[n].nState[m] != cExtbSetup::eIOModes_Unused) {
				if(sValue) {
          char* tmp=NULL;
          asprintf(&tmp,"%s,%d",sValue,theSetup.m_ioLEDMode[n].nState[m]);	
          free(sValue);
          sValue = tmp;
        }
				else
					asprintf(&sValue,"%d",theSetup.m_ioLEDMode[n].nState[m]);
			}
	  }
    if(sValue && theSetup.m_ioLEDMode[n].nReverse) {
      char* tmp=NULL;
      asprintf(&tmp,"%s,reverse",sValue);	
      free(sValue);
      sValue = tmp;
    }
    SetupStore(sz,sValue); 
    if(sValue) {
      free(sValue);
      sValue = NULL;
    }
  }
  for(unsigned int n=0;n<memberof(theSetup.m_ioLEDMode);++n) {
    snprintf(sz,sizeof(sz),"FlashMode%d",n + 1);  

	  for(unsigned int m=0;m<memberof(theSetup.m_ioLEDMode[0].nFlash);++m){
	   		if(theSetup.m_ioLEDMode[n].nFlash[m] != cExtbSetup::eIOModes_Unused) {
				if(sValue) {
          char* tmp=NULL;
          asprintf(&tmp,"%s,%d",sValue,theSetup.m_ioLEDMode[n].nFlash[m]);	
          free(sValue);
          sValue = tmp;
        }
				else
					asprintf(&sValue,"%d",theSetup.m_ioLEDMode[n].nFlash[m]);
			}
	  }
    if(sValue && theSetup.m_ioLEDMode[n].nFlashReverse) {
      char* tmp=NULL;
      asprintf(&tmp,"%s,reverse",sValue);	
      free(sValue);
      sValue = tmp;
    }
    if(sValue && theSetup.m_ioLEDMode[n].nFlashImportant) {
      char* tmp=NULL;
      asprintf(&tmp,"%s,important",sValue);	
      free(sValue);
      sValue = tmp;
    }
    SetupStore(sz,sValue); 
    if(sValue) {
      free(sValue);
      sValue = NULL;
    }
  }

  // store Setup for all Outputs (Output1..Output2...)
  for(unsigned int n=0;n<memberof(theSetup.m_ioOutputMode);++n) {
    snprintf(sz,sizeof(sz),"Output%d",n + 1);  
  
	  for(unsigned int m=0;m<memberof(theSetup.m_ioOutputMode[0].nState);++m){
	   		if(theSetup.m_ioOutputMode[n].nState[m] != cExtbSetup::eIOModes_Unused) {
				  if(sValue) {
            char* tmp=NULL;
            asprintf(&tmp,"%s,%d",sValue,theSetup.m_ioOutputMode[n].nState[m]);	
            free(sValue);
            sValue = tmp;
					}
	  			else
  				asprintf(&sValue,"%d",theSetup.m_ioOutputMode[n].nState[m]);
			}
	  }
    if(sValue && theSetup.m_ioOutputMode[n].nReverse) {
      char* tmp=NULL;
      asprintf(&tmp,"%s,reverse",sValue);	
      free(sValue);
      sValue = tmp;
    }
    SetupStore(sz,sValue); 
    if(sValue) {
    free(sValue);
      sValue = NULL;
    }
  }
  
  if((m_nOldVideoModeDVB != m_nVideoModeDVB) // send only if changed
     || (m_nOldVideoModeVGA != m_nVideoModeVGA) 
     || (m_nOldVideoModeVGA != m_nVideoModeVGA) 
     || (m_nOldScartPin8Mode != m_nScartPin8Mode)  
     || (m_nOldVideoSourceOnBoot != m_nVideoSourceOnBoot)) {

    SetStatus(tr("send settings to controller"));
  
    if(m_nOldVideoModeDVB != m_nVideoModeDVB) {
      switch(m_nVideoModeDVB) {
      case eRGB:  m_pExt->send("F_DVB_RGB"); break;
      case eSVID: m_pExt->send("F_DVB_CS");  break;
      }
    }
    
    if(m_nOldVideoModeVGA != m_nVideoModeVGA) {
      switch(m_nVideoModeVGA) {
      case eRGB:  m_pExt->send("F_VGA_RGB"); break;
      case eSVID: m_pExt->send("F_VGA_CS");  break;
      }
    }
    
    if(m_nOldVideoModeVGA != m_nVideoModeVGA) {
      switch(m_nVideoModeAUX) {
      case eRGB:  m_pExt->send("F_AUX_RGB"); break;
      case eSVID: m_pExt->send("F_AUX_CS");  break;
      }
    }
    
    // Set which Mode is used for Scart Pin 8
    if(m_nOldScartPin8Mode != m_nScartPin8Mode) { // send only if changed
      switch(m_nScartPin8Mode) {
        case eF_SC8_PWR: m_pExt->send("F_SC8_ON_PWR"); break;
        case eF_SC8_VDR: m_pExt->send("F_SC8_ON_VDR"); break;
        case eF_SC8_OFF: m_pExt->send("F_SC8_OFF"); break;
      }
    }
    
    // Set which Source is used during boot
    if(m_nOldVideoSourceOnBoot != m_nVideoSourceOnBoot) { // send only if changed
      switch(m_nVideoSourceOnBoot) {
        case eF_BOOT_VGA: m_pExt->send("F_BOOT_VGA"); break;
        case eF_BOOT_AUX: m_pExt->send("F_BOOT_AUX"); break;
        case eF_BOOT_OFF: m_pExt->send("F_BOOT_OFF"); break;
      }
    }
    SetStatus(NULL);
  }
  
  m_pExt->Update(true);
}
