#include "prefdlg.h"
#include "adapter.h"
#include "pixmaps/gear.xpm"


DriverWidget::DriverWidget(QWidget *parent, const char *name):QWidget(parent, name)
{
  char     buffer[4];
  
  GBox = new QGroupBox(this);
  GBox->setGeometry(10, 8, 328, 314);
  GBox->setTitle(klocale->translate("Driver Setup"));
  
  Modulechk = new QCheckBox(klocale->translate("Load driver as a module"), this);
  Modulechk->adjustSize();
  Modulechk->setGeometry(20, 34, Modulechk->width(), Modulechk->height());
  Modulechk->setChecked((ISDNData.General)->loadasmodule);
  connect(Modulechk, SIGNAL(clicked()), SLOT(slotModuleLoadChanged()));

  pmGear = new QLabel(this);
  pmGear->setPixmap(gear_xpm);
  pmGear->setGeometry(290, 26, 38, 38);

  Modprobelabel = new QLabel(klocale->translate("modprobe Path:"), this);
  Modprobelabel->setGeometry(50, 72, 95, 24);
  
  Modprobe = new QLineEdit(this);
  Modprobe->setGeometry(150, 72, 176, 24);
  Modprobe->setMaxLength(PATHSIZE);
  Modprobe->setText((ISDNData.General)->modprobepath.data());
  // connect(Modprobe, SIGNAL(textChanged(const char *)), SLOT(slotModPathchanged(const char *)));

  Browse = new QPushButton(klocale->translate("Browse..."), this);
  Browse->setGeometry(252, 104, 74, 25);  
  connect(Browse, SIGNAL(clicked()), SLOT(slotBrowseModPath()));
  
  Adapterlabel = new QLabel(klocale->translate("ISDN Adapter Type:"), this);
  Adapterlabel->setGeometry(24, 144, 120, 24);
  
  Adbox = new QComboBox(false, this);
  for (ushort i = 0; i < 5; i++) Adbox->insertItem((ad.Name[i]).data());
  Adbox->setGeometry(150, 144, 176, 24);
  Adbox->setCurrentItem((ISDNData.General)->adapter);
  connect(Adbox, SIGNAL(activated(int)), SLOT(slotAdapterChanged(int)));

  Iolabel = new QLabel(klocale->translate("I/O Base Addresses:"), this);
  Iolabel->setGeometry(20, 182, 114, 24);
  
  Ioaddr0 = new QLineEdit(this);
  Ioaddr0->setGeometry(150, 182, 60, 24);
  Ioaddr0->setMaxLength(6);
  Ioaddr0->setText((ISDNData.General)->iobase0.data());
  // connect(Ioaddr0, SIGNAL(textChanged(const char *)), SLOT(slotIOAddrChanged(const char *)));

  Ioaddr1 = new QLineEdit(this);
  Ioaddr1->setGeometry(220, 182, 60, 24);
  Ioaddr1->setMaxLength(6);
  Ioaddr1->setText((ISDNData.General)->iobase1.data());
  // connect(Ioaddr1, SIGNAL(textChanged(const char *)), SLOT(slotIOAddrChanged(const char *)));

  Intlabel = new QLabel(klocale->translate("Interrupt:"), this);
  Intlabel->setGeometry(86, 214, 50, 24);

  Interrupt = new QLineEdit(this);
  Interrupt->setGeometry(150, 214, 40, 24);
  Interrupt->setMaxLength(2);
  sprintf(buffer, "%i", (ISDNData.General)->interrupt);
  Interrupt->setText(buffer);
  // connect(Interrupt, SIGNAL(textChanged(const char *)), SLOT(slotInterruptChanged(const char *)));
 
  Memlabel = new QLabel(klocale->translate("Membase:"), this);
  Memlabel->setGeometry(76, 246, 58, 24);
  
  Membase = new QLineEdit(this);
  Membase->setGeometry(150, 246, 60, 24);
  Membase->setMaxLength(8);
  Membase->setText((ISDNData.General)->membase.data());

  Protlabel = new QLabel(klocale->translate("D Channel Protocol:"), this);
  Protlabel->setGeometry(22, 284, 120, 24);

  Protobox = new QComboBox(false, this);
  Protobox->setGeometry(150, 284, 150, 24);
  Protobox->insertItem("1TR6");
  Protobox->insertItem("Euro ISDN (EDSS1)");
  Protobox->insertItem("Leased Line");  
  Protobox->setCurrentItem((ISDNData.General)->protocol);
  connect(Protobox, SIGNAL(activated(int)), SLOT(slotProtocolChanged(int)));
  
  setParamState();
  setModState((ISDNData.General)->loadasmodule);  
}


void DriverWidget::setModState(bool state)
{
  Modprobelabel->setEnabled(state);
  Modprobe->setEnabled(state);
  Browse->setEnabled(state);
  Adapterlabel->setEnabled(state);
  Adbox->setEnabled(state);
  if (!state)
  {
    Iolabel->setEnabled(state);
    Ioaddr0->setEnabled(state);
    Ioaddr1->setEnabled(state);
    Memlabel->setEnabled(state);
    Membase->setEnabled(state);
  }
  Intlabel->setEnabled(state);
  Interrupt->setEnabled(state);
  Protlabel->setEnabled(state);
  Protobox->setEnabled(state);
  
  (ISDNData.General)->loadasmodule = state;
}


void DriverWidget::setParamState(void)
{
  ushort curr = Adbox->currentItem();
  
  Iolabel->setEnabled(ad.NeedIO1[curr]);
  Ioaddr0->setEnabled(ad.NeedIO1[curr]);
  Ioaddr1->setEnabled(ad.NeedIO2[curr]);
  Memlabel->setEnabled(ad.NeedMem[curr]);
  Membase->setEnabled(ad.NeedMem[curr]);
}


void DriverWidget::slotBrowseModPath(void)
{
  QFileDialog *Browser = new QFileDialog("/sbin", "modprobe", this, "", true);
  Browser->setCaption(klocale->translate("Choose modprobe Path"));

  QString ModprobeSel;
  
  if (Browser->exec() == QDialog::Accepted) ModprobeSel = Browser->selectedFile();
  if (!ModprobeSel.isNull())
  {
    Modprobe->setText(ModprobeSel.data());
    // emit a SIGNAL here ?
  }
  
  delete (Browser);
}


void DriverWidget::slotModuleLoadChanged(void)
{
  setParamState();
  setModState(Modulechk->isChecked()); // Registration to ISDNData.General is done here.
}


void DriverWidget::slotAdapterChanged(int Adapter)
{
  (ISDNData.General)->adapter = Adapter;
  setParamState();
}


void DriverWidget::slotProtocolChanged(int protocol)
{
  (ISDNData.General)->protocol = protocol;
}


bool DriverWidget::isValidIOAddr(ushort port)
{
  char     buffer[8] = "0x0000", newaddr[8], addr[8], *ioaddr;
  ushort   addrlen = 0;
  Adapter  ad;
  
  if ((port == 0) && !(ad.NeedIO1[(ISDNData.General)->adapter])) return (true);
  if ((port == 1) && !(ad.NeedIO2[(ISDNData.General)->adapter])) return (true);
  
  if (port == 0) strncpy(addr, Ioaddr0->text(), 8);
  else strncpy(addr, Ioaddr1->text(), 8);
  ioaddr = addr;
  
  while (*ioaddr == ' ') ioaddr++;
  
  if (*ioaddr != '\0')
  {
    if ((*(ioaddr++) == '0') && (*(ioaddr++) == 'x'))
    {
      while ((isxdigit(*ioaddr)) && (addrlen < 4)) newaddr[addrlen++] = toupper(*ioaddr++);
      newaddr[addrlen] = '\0';
    }
    else return (false); 
  }
  else return (false);
  
  if (*ioaddr != '\0') return (false);
  strncpy(buffer+6-addrlen, newaddr, addrlen);
  if (port == 0) (ISDNData.General)->iobase0 = buffer;
  else (ISDNData.General)->iobase1 = buffer;
  fprintf(stderr, "I/O Base %i changed to %s\n", port, buffer);
  return (true);
}


bool DriverWidget::isValidInterrupt(void)
{
  uint tmpint = atoi(Interrupt->text());
  if (tmpint <= 15) 
  {
    (ISDNData.General)->interrupt = tmpint;
    return (true);
  }
  else return (false);			       
}


bool DriverWidget::isValidMembase(void)
{
  char     buffer[10] = "0x00000", newaddr[8], addr[8], *memaddr;
  ushort   addrlen = 0;
  Adapter  ad;
  
  if (!(ad.NeedMem[(ISDNData.General)->adapter])) return (true);
  
  strncpy(addr, Membase->text(), 10);
  memaddr = addr;
  
  while (*memaddr == ' ') memaddr++;
  
  if (*memaddr != '\0')
  {
    if ((*(memaddr++) == '0') && (*(memaddr++) == 'x'))
    {
      while ((isxdigit(*memaddr)) && (addrlen < 5)) newaddr[addrlen++] = toupper(*memaddr++);
      newaddr[addrlen] = '\0';
    }
    else return (false); 
  }
  else return (false);
  
  if (*memaddr != '\0') return (false);
  strncpy(buffer+7-addrlen, newaddr, addrlen);
  (ISDNData.General)->membase = buffer;
  fprintf(stderr, "Membase changed to %s\n", buffer);
  return (true);
}


void DriverWidget::setIOBase(ushort port, QString base)
{
  if (port == 0) Ioaddr0->setText(base.data());
  else Ioaddr1->setText(base.data());
}


void DriverWidget::setInterrupt(char * inter)
{
  Interrupt->setText(inter);
}


void DriverWidget::setMembase(QString base)
{
  Membase->setText(base.data());
}

