
#include "menusetup.h"
#include "helpfunc.h"
#include "i18n.h"
#include "pvr.h"
#include "ptv.h"

static cOsdItem *b1, *b2, *b3, *b4, *b5, *b6, *b7, *b8;

static const char *Color[] =
  {
  "[                                  ]",
  "[|                                 ]",
  "[||                                ]",
  "[|||                               ]",
  "[||||                              ]",
  "[|||||                             ]",
  "[||||||                            ]",
  "[|||||||                           ]",
  "[||||||||                          ]",
  "[|||||||||                         ]",
  "[||||||||||                        ]",
  "[|||||||||||                       ]",
  "[||||||||||||                      ]",
  "[|||||||||||||                     ]",
  "[||||||||||||||                    ]",
  "[|||||||||||||||                   ]",
  "[||||||||||||||||                  ]",
  "[|||||||||||||||||                 ]",
  "[||||||||||||||||||                ]",
  "[|||||||||||||||||||               ]",
  "[||||||||||||||||||||              ]",
  "[|||||||||||||||||||||             ]",
  "[||||||||||||||||||||||            ]",
  "[|||||||||||||||||||||||           ]",
  "[||||||||||||||||||||||||          ]",
  "[|||||||||||||||||||||||||         ]",
  "[||||||||||||||||||||||||||        ]",
  "[|||||||||||||||||||||||||||       ]",
  "[||||||||||||||||||||||||||||      ]",
  "[|||||||||||||||||||||||||||||     ]",
  "[||||||||||||||||||||||||||||||    ]",
  "[|||||||||||||||||||||||||||||||   ]",
  "[||||||||||||||||||||||||||||||||  ]",
  "[||||||||||||||||||||||||||||||||| ]",
  "[||||||||||||||||||||||||||||||||||]"
  };

static const char *Dnr[] =
  {
  "[                                ]", //0
  "[||                              ]", //1
  "[||||                            ]", //2
  "[||||||                          ]", //3
  "[||||||||                        ]", //4
  "[||||||||||                      ]", //5
  "[||||||||||||                    ]", //6
  "[||||||||||||||                  ]", //7 
  "[||||||||||||||||                ]", //8
  "[||||||||||||||||||              ]", //9
  "[||||||||||||||||||||            ]", //10
  "[||||||||||||||||||||||          ]", //11
  "[||||||||||||||||||||||||        ]", //12
  "[||||||||||||||||||||||||||      ]", //13
  "[||||||||||||||||||||||||||||    ]", //14
  "[||||||||||||||||||||||||||||||  ]", //15
  "[||||||||||||||||||||||||||||||||]"  //16
  };

int getHandle(int dev) {
  int fd = -1;
  char devstr[64];
  sprintf(devstr, "/dev/video%d", dev);
  fd = open(devstr, O_RDWR | O_NONBLOCK);
  if (fd<0) d(0, "getHandle: couldn't get handle.");
  return fd;
  }

cMenuSetupPTV::cMenuSetupPTV(cPluginPTV *PluginPTV) :
   PluginPTV(PluginPTV)
  {
  const char* redButton=tr(" ");
  const char* greenButton=tr("Channel Scan");
  const char* yellowButton=tr(" ");
  const char* blueButton=tr(" ");
  tmpsetup = ptvsetup;
  Clear();
  SetSection(tr("Setup.PTV_$PTV_"));
  AddNewCategory(tr("Setup.PTV_$Picture Properties"));
  Add(b1 = new cMenuEditStraItem(tr("Setup.PTV_$Brightness"),      &tmpsetup.brightness, \
               sizeof(Color) / sizeof(char *), Color));
  Add(b2 = new cMenuEditStraItem(tr("Setup.PTV_$Contrast"),        &tmpsetup.contrast, \
               sizeof(Color) / sizeof(char *), Color));
  Add(b3 = new cMenuEditStraItem(tr("Setup.PTV_$Color"),           &tmpsetup.color, \
               sizeof(Color) / sizeof(char *), Color));
  Add(b4 = new cMenuEditStraItem(tr("Setup.PTV_$Hue"),             &tmpsetup.hue, \
               sizeof(Color) / sizeof(char *), Color));
  Add(b5 = new cMenuEditStraItem(tr("Setup.PTV_$Aspect"),               &tmpsetup.aspect, 4, aspects));
  Add(b6 = new cMenuEditStraItem(tr("Setup.PTV_$3:2 pulldown"),         &tmpsetup.pulldown, 2, pulldowns));
  Add(new cMenuEditIntItem( tr("Setup.PTV_$Audio volume"),         &tmpsetup.volume, 0, 100));
  Add(b7 = new cMenuEditStraItem(tr("Setup.PTV_$Spatial Filter"),  &tmpsetup.dnr_spatial, \
               sizeof(Dnr) / sizeof(char *), Dnr));
  Add(b8 = new cMenuEditStraItem(tr("Setup.PTV_$Temporal Filter"), &tmpsetup.dnr_temporal, \
               sizeof(Dnr) / sizeof(char *), Dnr));
  AddNewCategory(tr("Setup.PTV_$Various"));
  Add(new cMenuEditIntItem( tr("Setup.PTV_$Debug level"),          &tmpsetup.debug,  0, 9));
  Add(new cMenuEditStraItem(tr("Setup.PTV_$Debug output"),         &tmpsetup.logger, 4, loggers));
  SetHelp(redButton, greenButton, yellowButton, blueButton);
  SetCurrent(Get(1));
  }

void cMenuSetupPTV::AddNewCategory(const char* title)
  {
  char *buffer = NULL;
  asprintf(&buffer, "___ %s _____________________________________________________________", \
           title );
  cOsdItem *item = new cOsdItem(buffer);
  free(buffer);
  Add(item);
  }

cOsdItem *cMenuSetupPTV::Item(const char *name, const int num)
  {
  auto char buf[32];
  snprintf(buf, sizeof(buf), "%d", num);
  return Item(name, buf);
  }

cOsdItem *cMenuSetupPTV::Item(const char *name, const double num)
  {
  auto char buf[32];
  snprintf(buf, sizeof(buf), "%.3f", num);
  return Item(name, buf);
  }

cOsdItem *cMenuSetupPTV::Item(const char *name, const char *text)
  {
  char *buffer = NULL;
  asprintf(&buffer, "%s:\t%s", name, text);
  cOsdItem *item = new cOsdItem(buffer, osBack);
  free(buffer);
  return item;
  }

void cMenuSetupPTV::PictureProperties(void) {
  int i, fd = -1;
  d(3, "cMenuSetupPTV::PictureProperties()");
  for (i=0; i < MAX_DEV_NUM; i++) {
    if (PluginPTV->PTV_Dev_Exists(i)) {
      fd = getHandle(PluginPTV->GetVideodev(i));
      setControl(fd, tmpsetup.brightness, tmpsetup.contrast,\
                tmpsetup.color, tmpsetup.hue);
      setVolume(fd,tmpsetup.volume);
      d(0, "PictureProperties setCodec");
      setCodec (fd, tmpsetup.aspect, tmpsetup.pulldown,\
                tmpsetup.dnr_spatial, tmpsetup.dnr_temporal, tmpsetup.videonorm);
      close(fd);
      }
    else
      break;
    } 
  }

static bool check(int *cur, int ofs, int max)
  {
  if (ofs == -1)
    {
    if (*cur > 0)
      {
      *cur -= 1;
      return true;
      }
    }
  else
    {
    if (*cur < max)
      {
      *cur += 1;
      return true;
      }
    }   
  return false; 
  }

eOSState cMenuSetupPTV::ProcessKey(eKeys Key)
  {
  cOsdItem *item = Get(Current());
  int       val  = 0;
  int       i, fd = -1;
  switch (Key) {
    case kLeft     : val = -1;  break;
    case kRight    : val = +1;  break;
    case k0 ... k9 : val = Key; break; 
    default        : val = 0;   break;
    }
  if (val)
    {
    if (item == b1)
      {
      if (check(&tmpsetup.brightness, val, 34))
        PictureProperties();
      return osContinue;
      }
    else if (item == b2)
      {
      if (check(&tmpsetup.contrast, val, 34))
        PictureProperties();
      return osContinue;
      }
    else if (item == b3)
      {
      if (check(&tmpsetup.color, val, 34))
        PictureProperties();
      return osContinue;
      }
    else if (item == b4)
      {
      if (check(&tmpsetup.hue, val, 34))
        PictureProperties();
      return osContinue;
      }
    else if (item == b5)
      {
      if (check(&tmpsetup.aspect, val, 2))
        PictureProperties();
      return osContinue;
      }
    else if (item == b6)
      {
      if (check(&tmpsetup.pulldown, val, 2))
        PictureProperties();
      return osContinue;
      }
    else if (item == b7)
      {
      if (check(&tmpsetup.dnr_spatial, val, 16))
        PictureProperties();
      return osContinue;
      }
    else if (item == b8)
      {
      if (check(&tmpsetup.dnr_temporal, val, 16))
        PictureProperties();
      return osContinue;
      }
    else 
        for (i=0; i < MAX_DEV_NUM; i++) {
          if (PluginPTV->PTV_Dev_Exists(i)) {
            fd = getHandle(PluginPTV->GetVideodev(i));
            setCodec (fd, tmpsetup.aspect, tmpsetup.pulldown,\
                     tmpsetup.dnr_spatial, tmpsetup.dnr_temporal, tmpsetup.videonorm);
            setControl(fd, tmpsetup.brightness, tmpsetup.contrast,\
                     tmpsetup.color, tmpsetup.hue);
            setVolume(fd,tmpsetup.volume);
            close(fd);
            }
          else
            break;
          } 
    }
  eOSState state = cOsdMenu::ProcessKey(Key);
  switch (Key)
    {
    case kRed    : state = osUser1;
                   break; 
    case kGreen  : state = osUser2;
                   break; 
    case kYellow : state = osUser3;
                   break; 
    case kBlue   : state = osUser4;
                   break;    
    default      : break;
    }
  switch (state)
    {
    case osUnknown : if (Key == kOk)
                       {
                       Store();
                       for (i=0; i < MAX_DEV_NUM; i++) {
                         if (PluginPTV->PTV_Dev_Exists(i)) {
                           fd = getHandle(PluginPTV->GetVideodev(i));
                            setCodec (fd, tmpsetup.aspect, tmpsetup.pulldown, \
                                          tmpsetup.dnr_spatial, tmpsetup.dnr_temporal,\
                                          tmpsetup.videonorm);
                            setControl(fd, tmpsetup.brightness, tmpsetup.contrast,\
                                           tmpsetup.color, tmpsetup.hue);
                            setVolume(fd, tmpsetup.volume);
                            close(fd);
                            }
                          else
                            break;
                          } 
                       state = osBack;
                       }
                     break;
    case osUser1   : state = osContinue; /*red button*/
                     d(5, "Menu: red button pressed. Not implemented.");
                     break;
    case osUser2   : state = osContinue;/*green button*/
                     d(5, "Menu: green button pressed. Channel Scan");
                     for (i=0; i < MAX_DEV_NUM; i++) {
                       if (PluginPTV->PTV_Dev_Exists(i))                                     
                       for (i=0; i < MAX_DEV_NUM; i++) {
                         if (PluginPTV->PTV_Dev_Exists(i)) {
                           fd = getHandle(PluginPTV->GetVideodev(i));                          
                           if (!doChannelScan(fd)) {
                             close(fd);
                             break;
                             }
                           }
                         }  
                       }
                     break;
    case osUser3   : state = osContinue;/*yellow button*/
                     d(5, "Menu: yellow button pressed. Not implemented.");
                     break;
    case osUser4   : state = osContinue;/*blue button*/
                     d(5, "Menu: blue button pressed. Not implemented.");
                     break;
    case osBack    : d(1, "[Back] pressed, undoing all changes");
                     tmpsetup = ptvsetup;
                     PictureProperties();
                     break; 
    default        : break;
    }
  return state;
  }

void cMenuSetupPTV::Store(void)
  {
  d(5, "cMenuSetupPTV::Store()");
  ptvsetup = tmpsetup;
  SetupStore("debug",            ptvsetup.debug);
  SetupStore("Logger",           ptvsetup.logger);
  SetupStore("MixerVolume",      ptvsetup.volume);
  SetupStore("Brightness",       ptvsetup.brightness);
  SetupStore("Hue",              ptvsetup.hue);
  SetupStore("Color",            ptvsetup.color);
  SetupStore("Contrast",         ptvsetup.contrast);
  SetupStore("Aspect",      	 ptvsetup.aspect);
  SetupStore("Pulldown",      	 ptvsetup.pulldown);
  SetupStore("DNRspatial",       ptvsetup.dnr_spatial);
  SetupStore("DNRtemporal",      ptvsetup.dnr_temporal);
  }
