/* 
 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "stdafx.h"

#include "edit_table_data_wizard.h"
#include "grt/grt_manager.h"
#include "grtpp_util.h"
#include "base/string_utilities.h"
#include "sqlide/wb_sql_editor_form.h"
#include "sqlide/wb_sql_editor_tree_controller.h"

using namespace base;

//----------------- TableSelectionPage ----------------------------------------------------------------

TableSelectionPage::TableSelectionPage(WizardForm* wizard)
:
WizardPage(wizard, "table selection page"),
_schema_selector_contents(true),
_table_selector_contents(true),
_log_panel(mforms::TitledBoxPanel),
_log_text(mforms::BothScrollBars),
_context(NULL)
{
  set_short_title(_("Table Selection"));
  set_title(_("Database Schema and Table Selection"));

  // schema selector
  _schema_selector_heading.set_text(_("Please select the Database Schema that holds the table you want to edit."));
  _schema_selector_heading.set_wrap_text(true);
  add(&_schema_selector_heading, false, false);

  add(&_schema_selector_table, false, false);
  _schema_selector_table.set_row_count(1);
  _schema_selector_table.set_column_count(2);
  _schema_selector_table.set_column_spacing(4);

  _schema_selector_caption.set_text_align(mforms::WizardLabelAlignment);
  _schema_selector_caption.set_text(_("Schema:")); 
  _schema_selector_table.add(&_schema_selector_caption, 0, 1, 0, 1, mforms::HFillFlag);

  _schema_selector_contents.set_spacing(8);
  _schema_selector_table.add(&_schema_selector_contents, 1, 2, 0, 1, mforms::HExpandFlag|mforms::HFillFlag);

  _schema_selector_contents.add(&_schema_selector, true, true);
  scoped_connect(_schema_selector.signal_changed(),boost::bind(&TableSelectionPage::schema_changed, this));

  // table selector
  _table_selector_heading.set_text(_("Select the table you want to edit."));
  _table_selector_heading.set_wrap_text(true);
  add(&_table_selector_heading, false, false);

  add(&_table_selector_table, false, false);
  _table_selector_table.set_row_count(1);
  _table_selector_table.set_column_count(2);
  _table_selector_table.set_column_spacing(4);

  _table_selector_caption.set_text_align(mforms::WizardLabelAlignment);
  _table_selector_caption.set_text(_("Table:")); 
  _table_selector_table.add(&_table_selector_caption, 0, 1, 0, 1, mforms::HFillFlag);

  _table_selector_contents.set_spacing(8);
  _table_selector_table.add(&_table_selector_contents, 1, 2, 0, 1, mforms::HExpandFlag|mforms::HFillFlag);

  _table_selector_contents.add(&_table_selector, true, true);
  scoped_connect(_table_selector.signal_changed(),boost::bind(&TableSelectionPage::table_changed, this)); 

  // last message
  _last_message.set_text(_(
    "Press [Finish] to start editing the table data.\n"
    "An SQL Editor will be opened and the table data will be displayed for editing."));
  _last_message.set_wrap_text(true);
  add(&_last_message, false, false);

  // log panel
  add(&_log_panel, true, true);
  _log_panel.set_title(_("Database Connection Log"));
  _log_panel.show(false);

  _log_text.set_read_only(true);
  _log_panel.add(&_log_text);
}

//--------------------------------------------------------------------------------------------------

void TableSelectionPage::enter(bool advancing)
{
  if (advancing)
  {
    std::string exception_message;
    
    _log_text.clear();
    _log_panel.show(false);
    _last_message.show(true);
    relayout();

    try
    {
      _schema_selector.clear();
      sql::ConnectionWrapper dbc_conn= _db_conn->get_dbc_connection();
      std::auto_ptr<sql::ResultSet> rs(dbc_conn->getMetaData()->getSchemata());
      while (rs->next())
      {
        std::string name= rs->getString(1);
        _schema_selector.add_item(name);
      }
      _log_text.set_value(_("Database connection completed successfully."));
      schema_changed();
    }
    catch (std::exception &e)
    {
      std::string exception_message= strfmt(_("Error occured: %s"), e.what());
      _log_text.set_value(exception_message);
      _form->set_problem(exception_message);
      _log_panel.show(true);
      _last_message.show(false);
      relayout();
    }

  }
}

//--------------------------------------------------------------------------------------------------

void TableSelectionPage::schema_changed()
{
  try
  {
    _table_selector.clear();
    if (!_schema_selector.get_string_value().empty())
    {
      sql::ConnectionWrapper dbc_conn= _db_conn->get_dbc_connection();
      std::auto_ptr<sql::ResultSet> rs(dbc_conn->getMetaData()->getSchemaObjects("", _schema_selector.get_string_value(), "table"));
      while (rs->next())
      {
        std::string name= rs->getString(4);
        _table_selector.add_item(name);
      }
      table_changed();
    }
  }
  catch (std::exception &e)
  {
    _form->set_problem(strfmt(_("Failed to fetch table list: %s"), e.what()));
  }
}

//--------------------------------------------------------------------------------------------------

void TableSelectionPage::table_changed()
{
  //validate(); // Commented out to fix bug #57127
                // The validate check is done in allow_next
}

//--------------------------------------------------------------------------------------------------

void TableSelectionPage::do_validate()
{
  if (_schema_selector.get_string_value().empty() || _table_selector.get_string_value().empty())
    _form->set_problem(_("Either schema or table is not selected."));
  else
    _form->clear_problem();
}

//--------------------------------------------------------------------------------------------------

bool TableSelectionPage::allow_next()
{
  return !(_schema_selector.get_string_value().empty() || _table_selector.get_string_value().empty());
}

//--------------------------------------------------------------------------------------------------

bool TableSelectionPage::advance()
{
  db_mgmt_ConnectionRef conn = _db_conn->get_connection();
  if (conn.is_valid())
  {
    _context->show_status_text("Opening SQL Editor...");          
    Db_sql_editor::Ref db_sql_editor(_context->add_new_query_window(conn));
    if (db_sql_editor)
      db_sql_editor->get_live_tree()->schema_object_activated(
        "edit_data",
        wb::LiveSchemaTree::Table,
        _schema_selector.get_string_value(),
        _table_selector.get_string_value());
  }
  
  return true;
}

//--------------------------------------------------------------------------------------------------

std::string TableSelectionPage::next_button_caption()
{
  return _("Finish");
}

//--------------------------------------------------------------------------------------------------

void TableSelectionPage::set_db_connection(DbConnection *value)
{
  _db_conn= value;
}

//----------------- EditTableDataWizard ---------------------------------------------------------
void TableSelectionPage::set_context(wb::WBContext* context)
{
  _context= context;
}

//----------------- EditTableDataWizard ---------------------------------------------------------

EditTableDataWizard::EditTableDataWizard(wb::WBContext* context)
:
WizardForm(context->get_grt_manager()),
_db_conn(context->get_root()->rdbmsMgmt(), db_mgmt_DriverRef(), true),
_context(context)
{
  set_title(_("Edit Table Data"));

  _db_conn_page= new ConnectionPage(this);
  _db_conn_page->set_db_connection(&_db_conn);
  add_page(manage(_db_conn_page));

  _table_selection_page= new TableSelectionPage(this);
  _table_selection_page->set_db_connection(&_db_conn);
  _table_selection_page->set_context(_context);
  add_page(manage(_table_selection_page));
}

//--------------------------------------------------------------------------------------------------

EditTableDataWizard::~EditTableDataWizard()
{
  // Pages are freed by the WizardForm ancestor.
}

//--------------------------------------------------------------------------------------------------
