
/*!
  \file
  \brief Ethernet 接続用 Widget

  \author Satofumi KAMIMURA

  $Id: EthernetConnectionWidget.cpp 1988 2012-05-15 07:04:56Z satofumi $
*/

#include "EthernetConnectionWidget.h"
#include <QFile>
#include <QTextStream>
#include <QCompleter>

using namespace qrk;
using namespace std;


namespace
{
  const char CompleterFile[] = "ethernet_address.txt";
}


struct EthernetConnectionWidget::pImpl
{
  EthernetConnectionWidget* widget_;
  QStringList completer_address_;


  pImpl(EthernetConnectionWidget* widget) : widget_(widget)
  {
  }


  void initializeForm(void)
  {
    connect(widget_->connect_button_, SIGNAL(clicked(bool)),
            widget_, SLOT(connectPressed(bool)));

    loadCompleteAddress();
  }


  bool loadCompleteAddress(void)
  {
    // 入力候補を保存したファイルがあれば、読み出して入力候補として使う
    QFile file(CompleterFile);
    if (! file.open(QFile::ReadOnly)) {
      return false;
    }

    QTextStream fin(&file);
    while (true) {
      QString line = fin.readLine();
      if (line.isNull()) {
        break;
      }
      completer_address_ << line;
    }

    QCompleter* completer = new QCompleter(completer_address_, widget_);
    widget_->address_lineedit_->setCompleter(completer);

    return true;
  }


  bool saveCompleteAddress(void)
  {
    QFile file(CompleterFile);
    if (! file.open(QFile::WriteOnly | QFile::Truncate)) {
      return false;
    }

    QTextStream fout(&file);
    size_t n = completer_address_.size();
    for (size_t i = 0; i < n; ++i) {
      fout << completer_address_.at(i);
    }

    return true;
  }
};


EthernetConnectionWidget::EthernetConnectionWidget(QWidget* parent)
  : QWidget(parent), pimpl(new pImpl(this))
{
  setupUi(this);
  pimpl->initializeForm();
}


EthernetConnectionWidget::~EthernetConnectionWidget(void)
{
}


void EthernetConnectionWidget::setConnected(bool connected)
{
  connect_button_->setEnabled(true);
  connect_button_->setChecked(connected);

  if (connected) {
    // 今までにない接続アドレスの場合、追加して保存する
    QString connected_address = address().c_str();
    if (! pimpl->completer_address_.contains(connected_address)) {
      pimpl->completer_address_ << connected_address;
      pimpl->saveCompleteAddress();
    }
    connect_button_->setText(tr("Disconnect"));
  } else {
    connect_button_->setText(tr("Connect"));
  }
  address_lineedit_->setEnabled(! connected);
  port_spinbox_->setEnabled(! connected);

  connect_button_->setFocus();
}


bool EthernetConnectionWidget::isConnected(void) const
{
  return (connect_button_->isEnabled() && connect_button_->isChecked())
    ? true : false;
}


void EthernetConnectionWidget::setAddress(const std::string& address)
{
  address_lineedit_->setText(address.c_str());
}


std::string EthernetConnectionWidget::address(void) const
{
  return address_lineedit_->text().toStdString();
}


void EthernetConnectionWidget::setPort(unsigned short port)
{
  port_spinbox_->setValue(port);
}


unsigned EthernetConnectionWidget::port(void) const
{
  return port_spinbox_->value();
}


void EthernetConnectionWidget::setEnabled(bool enable)
{
  QWidget::setEnabled(enable);
}


void EthernetConnectionWidget::setFocus(void)
{
  connect_button_->setFocus();
}


void EthernetConnectionWidget::connectPressed(bool checked)
{
  // 接続ボタンが押下されたとき、setConnected() が呼ばれるまでボタンを無効にする
  connect_button_->setEnabled(false);
  string address = address_lineedit_->text().toStdString();
  unsigned short port = port_spinbox_->value();
  emit connectRequest(checked, address, port);
}
