// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gui/config_dialog/generic_table_editor.h"

#include <QtCore/QFile>
#include <QtGui/QFileDialog>
#include <QtGui/QtGui>
#include <algorithm>  // for unique
#include <cctype>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "base/file_stream.h"
#include "base/util.h"
#include "session/commands.pb.h"

namespace mozc {
namespace gui {
namespace {
const size_t kMaxEntrySize = 10000;

int GetTableHeight(QTableWidget *widget) {
  // Dragon Hack:
  // Here we use "龍" to calc font size, as it looks almsot square
  // const char kHexBaseChar[]= "龍";
  const char kHexBaseChar[]= "\xE9\xBE\x8D";
  const QRect rect =
      QFontMetrics(widget->font()).boundingRect(
          QObject::trUtf8(kHexBaseChar));
#ifdef OS_WIN
  return static_cast<int>(rect.height() * 1.3);
#else
  return static_cast<int>(rect.height() * 1.4);
#endif   // OS_WIN
}
}  // namespace

GenericTableEditorDialog::GenericTableEditorDialog(QWidget *parent,
                                                   size_t column_size)
    : QDialog(parent),
      edit_menu_(new QMenu(this)),
      column_size_(column_size) {
  setupUi(this);
  editorTableWidget->setAlternatingRowColors(true);
  setWindowFlags(Qt::WindowSystemMenuHint | Qt::Tool);
  editorTableWidget->setColumnCount(column_size_);

  CHECK_GT(column_size_, 0);

  // Mac style
#ifdef OS_MACOSX
  editorTableWidget->setShowGrid(false);
  layout()->setContentsMargins(0, 0, 0, 4);
  gridLayout->setHorizontalSpacing(12);
  gridLayout->setVerticalSpacing(12);
#endif  // OS_MACOSX

  editButton->setText(tr("Edit"));
  editButton->setMenu(edit_menu_);

  QObject::connect(edit_menu_,
                   SIGNAL(triggered(QAction *)),
                   this,
                   SLOT(OnEditMenuAction(QAction *)));

  QObject::connect(editorButtonBox,
                   SIGNAL(clicked(QAbstractButton *)),
                   this,
                   SLOT(Clicked(QAbstractButton *)));

  editorTableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
  connect(editorTableWidget, SIGNAL(customContextMenuRequested(const QPoint &)),
          this, SLOT(OnContextMenuRequested(const QPoint &)));

  editorTableWidget->horizontalHeader()->setStretchLastSection(true);
  editorTableWidget->horizontalHeader()->setSortIndicatorShown(true);
  editorTableWidget->horizontalHeader()->setHighlightSections(false);
  // Do not use QAbstractItemView::AllEditTriggers so that user can easily
  // select multiple items. See b/6488800.
  editorTableWidget->setEditTriggers(QAbstractItemView::AnyKeyPressed |
                                     QAbstractItemView::DoubleClicked |
                                     QAbstractItemView::SelectedClicked);
  editorTableWidget->setSortingEnabled(true);

  editorTableWidget->verticalHeader()->setResizeMode(QHeaderView::Fixed);
  editorTableWidget->verticalHeader()->setDefaultSectionSize(
      GetTableHeight(editorTableWidget));

  UpdateMenuStatus();
}

GenericTableEditorDialog::~GenericTableEditorDialog() {}

QTableWidget *GenericTableEditorDialog::mutable_table_widget() {
  return editorTableWidget;
}

const string &GenericTableEditorDialog::table() const {
  return table_;
}

string *GenericTableEditorDialog::mutable_table() {
  return &table_;
}

QMenu *GenericTableEditorDialog::mutable_edit_menu() {
  return edit_menu_;
}

bool GenericTableEditorDialog::LoadFromString(const string &str) {
  istringstream istr(str);
  return LoadFromStream(&istr);
}

void GenericTableEditorDialog::DeleteSelectedItems() {
  vector<int> rows;
  QList<QTableWidgetItem *> selected =
      editorTableWidget->selectedItems();

  // remember the last column as user chooses the
  // last rows from top to bottom in general.
  const int column = selected.isEmpty() ? 0 :
      selected.back()->column();

  for (int i = 0; i < selected.size(); ++i) {
    rows.push_back(selected[i]->row());
  }

  vector<int>::iterator last = unique(rows.begin(), rows.end());
  rows.erase(last, rows.end());

  if (rows.empty()) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("No entry is selected"));
    return;
  }

  // Choose next or prev item.
  QTableWidgetItem *item = editorTableWidget->item(rows.back() + 1, column);
  if (item == NULL) {
    item = editorTableWidget->item(rows.back() - 1, column);
  }

  // select item
  if (item != NULL) {
    editorTableWidget->setCurrentItem(item);
  }

  // remove from the buttom
  for (int i = rows.size() - 1; i >= 0; --i) {
    editorTableWidget->removeRow(rows[i]);
  }

  UpdateMenuStatus();
}

void GenericTableEditorDialog::InsertEmptyItem(int row) {
  editorTableWidget->verticalHeader()->hide();

  // It is important to disable auto-sorting before we programmatically edit
  // multiple items. Otherwise, one single edit of cell such as
  //   editorTableWidget->setItem(row, col, data);
  // will cause auto-sorting and the target row will be moved to different
  // place.
  const bool sorting_enabled = editorTableWidget->isSortingEnabled();
  if (sorting_enabled) {
    editorTableWidget->setSortingEnabled(false);
  }

  editorTableWidget->insertRow(row);
  for (size_t i = 0; i < column_size_; ++i) {
    editorTableWidget->setItem(row, i, new QTableWidgetItem(""));
  }
  QTableWidgetItem *item = editorTableWidget->item(row, 0);
  if (item != NULL) {
    editorTableWidget->setCurrentItem(item);
    editorTableWidget->scrollToItem(item,
                                    QAbstractItemView::PositionAtCenter);
    editorTableWidget->editItem(item);
  }

  // Restore auto-sorting setting if necessary.
  if (sorting_enabled) {
    // From the usability perspective, auto-sorting should be disabled until
    // a user explicitly enables it again by clicking the table header.
    // To achieve it, set -1 to the |logicalIndex| in setSortIndicator.
    editorTableWidget->horizontalHeader()->setSortIndicator(
        -1, Qt::AscendingOrder);
    editorTableWidget->setSortingEnabled(true);
  }

  UpdateMenuStatus();
}

void GenericTableEditorDialog::InsertItem() {
  QTableWidgetItem *current = editorTableWidget->currentItem();
  if (current == NULL) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("No entry is selected"));
    return;
  }
  InsertEmptyItem(current->row() + 1);
}

void GenericTableEditorDialog::AddNewItem() {
  if (editorTableWidget->rowCount() >= max_entry_size()) {
    QMessageBox::warning(
        this,
        windowTitle(),
        tr("You can't have more than %1 entries").arg(max_entry_size()));
    return;
  }

  InsertEmptyItem(editorTableWidget->rowCount());
}

void GenericTableEditorDialog::Import() {
  const QString filename =
  QFileDialog::getOpenFileName(this, tr("import from file"),
                               QDir::homePath());
  if (filename.isEmpty()) {
    return;
  }

  QFile file(filename);
  if (!file.exists()) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("File not found"));
    return;
  }

  const qint64 kMaxSize = 100 * 1024;
  if (file.size() >= kMaxSize) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("The specified file is too large (>=100K byte)"));
    return;
  }

  InputFileStream ifs(filename.toStdString().c_str());
  if (!LoadFromStream(&ifs)) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("Import failed"));
    return;
  }
}

void GenericTableEditorDialog::Export() {
  if (!Update()) {
    return;
  }

  const QString filename =
      QFileDialog::getSaveFileName(this, tr("export to file"),
          QDir::homePath() + QDir::separator() +
          QString(GetDefaultFilename().c_str()));
  if (filename.isEmpty()) {
    return;
  }

  OutputFileStream ofs(filename.toStdString().c_str());
  if (!ofs) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("Export failed"));
    return;
  }

  ofs << table();
}

void GenericTableEditorDialog::Clicked(QAbstractButton *button) {
  // Workaround for http://b/242686
  // By changing the foucs, incomplete entries in QTableView are
  // submitted to the model.
  editButton->setFocus(Qt::MouseFocusReason);

  switch (editorButtonBox->buttonRole(button)) {
    /// number of role might be increased in the future.
    case QDialogButtonBox::AcceptRole:
      if (Update()) {
        QDialog::accept();
      }
      break;
    default:
      QDialog::reject();
      break;
  }
}

void GenericTableEditorDialog::OnContextMenuRequested(const QPoint &pos) {
  QTableWidgetItem *item = editorTableWidget->itemAt(pos);
  if (item == NULL) {
    return;
  }

  QMenu *menu = new QMenu(this);
  QAction *edit_action = NULL;
  const QList<QTableWidgetItem *> selected_items =
      editorTableWidget->selectedItems();
  if (selected_items.count() == 1) {
    edit_action = menu->addAction(tr("Edit entry"));
  }
  QAction *rename_action = menu->addAction(tr("New entry"));
  QAction *delete_action = menu->addAction(tr("Remove entry"));
  QAction *selected_action = menu->exec(QCursor::pos());

  if (edit_action != NULL && selected_action == edit_action) {
    editorTableWidget->editItem(selected_items[0]);
  } else if (selected_action == rename_action) {
    AddNewItem();
  } else if (selected_action == delete_action) {
    DeleteSelectedItems();
  }
}

void GenericTableEditorDialog::UpdateOKButton(bool status) {
  QPushButton *button = editorButtonBox->button(QDialogButtonBox::Ok);
  if (button != NULL) {
    button->setEnabled(status);
  }
}

size_t GenericTableEditorDialog::max_entry_size() const {
  return kMaxEntrySize;
}

bool GenericTableEditorDialog::LoadFromStream(istream *is) {
  return true;
}

bool GenericTableEditorDialog::Update() {
  return true;
}

void GenericTableEditorDialog::UpdateMenuStatus() {}

void GenericTableEditorDialog::OnEditMenuAction(QAction *action) {}
}  // namespace gui
}  // namespace mozc
