/*******************************************************************************
 * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: www.phpeclipse.de
 ******************************************************************************/
package net.sourceforge.phpeclipse.actions;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import net.sourceforge.phpeclipse.PHPeclipsePlugin;
import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
import net.sourceforge.phpeclipse.ui.WebUI;
import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionDelegate;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.internal.dialogs.ListContentProvider;

import com.quantum.QuantumPlugin;
import com.quantum.adapters.DatabaseAdapter;
import com.quantum.model.Bookmark;
import com.quantum.model.BookmarkCollection;
import com.quantum.model.Entity;
import com.quantum.model.EntityFactory;
import com.quantum.model.NotConnectedException;
import com.quantum.sql.MultiSQLServer;
import com.quantum.sql.SQLResultSetCollection;
import com.quantum.sql.SQLResultSetResults;
import com.quantum.sql.SQLResults;
import com.quantum.ui.dialog.ExceptionDisplayDialog;
import com.quantum.util.connection.ConnectionUtil;
import com.quantum.view.tableview.TableView;

public class PHPOpenSQLTableEditorAction extends ActionDelegate implements
    IEditorActionDelegate {

  private IWorkbenchWindow fWindow;

  private PHPEditor fEditor;

  private IProject fProject;

  public void dispose() {
  }

  public void init(IWorkbenchWindow window) {
    this.fWindow = window;
  }

  public void selectionChanged(IAction action, ISelection selection) {
    if (!selection.isEmpty()) {
      if (selection instanceof TextSelection) {
        action.setEnabled(true);
      } else if (fWindow.getActivePage() != null
          && fWindow.getActivePage().getActivePart() != null) {
        //
      }
    }
  }

  private IWorkbenchPage getActivePage() {
    fWindow = fEditor.getEditorSite()
        .getWorkbenchWindow();
    IWorkbenchPage page = fWindow.getActivePage();
    return page;
  }

  public IContainer getWorkingLocation(IFileEditorInput editorInput) {
    if (editorInput == null || editorInput.getFile() == null) {
      return null;
    }
    return editorInput.getFile().getParent();
  }

  private IFile getIncludeFile(IProject project, IFileEditorInput editorInput,
      String relativeFilename) {
    //		IContainer container = getWorkingLocation(editorInput);
    //		String fullPath = project.getLocation().toString();
    Path path = new Path(relativeFilename);
    IFile file = project.getFile(path);
    return file;
  }

  public void run(IAction action) {
    if (fEditor == null) {
      IEditorPart targetEditor = fWindow.getActivePage().getActiveEditor();
      if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
        fEditor = (PHPEditor) targetEditor;
      }
    }
    if (fEditor != null) {
      //			TableView view = TableView.getInstance();

      //			determine the current Project from a (file-based) Editor
      fWindow = fEditor.getEditorSite().getWorkbenchWindow();
      IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
      fProject = f.getProject();

      ITextSelection selection = (ITextSelection) fEditor
          .getSelectionProvider().getSelection();
      IDocument doc = fEditor.getDocumentProvider().getDocument(
          fEditor.getEditorInput());
      int pos = selection.getOffset();
      //  System.out.println(selection.getText());
      String tableName = getSQLTableName(doc, pos);

      IViewPart viewPart = null;
      String view = "com.quantum.view.tableview.TableView";
      try {
        IWorkbenchPage page = QuantumPlugin.getDefault().getActivePage();
        viewPart = page.findView(view);
        if (viewPart == null) {
          viewPart = page.showView(view);
        }
        page.bringToTop(viewPart);
        getTables((TableView) viewPart, fProject, tableName);
      } catch (PartInitException e) {
        e.printStackTrace();
      }

    }
  }

  public void setActiveEditor(IAction action, IEditorPart targetEditor) {
    if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
      fEditor = (PHPEditor) targetEditor;
    }
  }

  private String getSQLTableName(IDocument doc, int pos) {
    Point word = null;
    int start = -1;
    int end = -1;

    try {

      int position = pos;
      char character;

      while (position >= 0) {
        character = doc.getChar(position);
        if (Character.isWhitespace(character) || (character == '\"')
            || (character == '\'') || (character == '\r')
            || (character == '\n'))
          break;
        --position;
      }

      start = position;

      position = pos;
      int length = doc.getLength();

      while (position < length) {
        character = doc.getChar(position);
        if (Character.isWhitespace(character) || (character == '\"')
            || (character == '\'') || (character == '\r')
            || (character == '\n'))
          break;
        ++position;
      }

      start++;
      end = position;

      if (end > start)
        word = new Point(start, end - start);

    } catch (BadLocationException x) {
    }

    if (word != null) {
      try {
        return doc.get(word.x, word.y);
      } catch (BadLocationException e) {
      }
    }
    return "";
  }

  public void getTables(TableView tableView, IProject project, String tableName) {
    // Get The Database bookmark from the Quantum SQL plugin:
    BookmarkCollection sqlBookMarks = BookmarkCollection.getInstance();
    if (sqlBookMarks != null) {
      String bookmarkString = ProjectPrefUtil.getMiscProjectsPreferenceValue(project,
          WebUI.PHP_BOOKMARK_DEFAULT);
      if (bookmarkString != null && !bookmarkString.equals("")) {
        Bookmark bookmark = sqlBookMarks.find(bookmarkString);
        ArrayList sqlList = new ArrayList();
        if (bookmark != null && !bookmark.isConnected()) {
          new ConnectionUtil().connect(bookmark, null);
        }
        if (bookmark != null && bookmark.isConnected()) {
          try {
            Connection connection = bookmark.getConnection();
            DatabaseMetaData metaData = connection.getMetaData();
            ConnectionUtil connectionUtil = new ConnectionUtil();
            Entity entity;
            DatabaseAdapter adapter;

            if (metaData != null) {
              String columnName;
              String prefixWithoutDollar = tableName;
              if (prefixWithoutDollar.charAt(0) == '$') {
                prefixWithoutDollar = prefixWithoutDollar.substring(1);
              }
              ResultSet set;
              set = metaData.getTables(null, null, "%" + prefixWithoutDollar
                  + "%", null);
              while (set.next()) {
                tableName = set.getString("TABLE_NAME");
                tableName = (tableName == null) ? "" : tableName.trim();
                if (tableName != null && tableName.length() > 0) {
                  sqlList.add(tableName);
                }
              }
              set.close();
              EntityFactory entityFactory = EntityFactory.getInstance();
              if (sqlList.size() == 1) {
                adapter = bookmark.getAdapter();
                entity = entityFactory.create(bookmark, null, (String) sqlList
                    .get(0), Entity.TABLE_TYPE, false);
                String query = adapter.getTableQuery(entity.getQualifiedName());

                try {
                  SQLResults results = MultiSQLServer.getInstance().execute(
                      bookmark, connectionUtil.connect(bookmark, fWindow.getShell()),  
                      entity, query);

                  if (results != null && results.isResultSet()) {
                    SQLResultSetCollection.getInstance().addSQLResultSet(
                        (SQLResultSetResults) results);
                  }
                } catch (SQLException e) {
                  ExceptionDisplayDialog.openError(fWindow.getShell(), null, null, e);
                }
                //								tableView.loadTable(entityFactory.create(
                //										bookmark, null,
                //										(String) sqlList.get(0),
                //										Entity.TABLE_TYPE));
              } else if (sqlList.size() > 1) {
                ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
                    PHPeclipsePlugin.getDefault().getWorkbench()
                        .getActiveWorkbenchWindow().getShell(), sqlList,
                    new ListContentProvider(), new LabelProvider(),
                    "Select the SQL table to open.");
                listSelectionDialog.setTitle("Multiple tablenames found");
                if (listSelectionDialog.open() == Window.OK) {
                  Object[] locations = listSelectionDialog.getResult();
                  if (locations != null) {
                    for (int i = 0; i < locations.length; i++) {
                      adapter = bookmark.getAdapter();
                      entity = entityFactory.create(bookmark, null,
                          (String) locations[i], Entity.TABLE_TYPE, false);
                      String query = adapter.getTableQuery(entity
                          .getQualifiedName());

                      try {
                        SQLResults results = MultiSQLServer.getInstance()
                            .execute(bookmark,
                                connectionUtil.connect(bookmark, fWindow.getShell()),
                                entity, query);

                        if (results != null && results.isResultSet()) {
                          SQLResultSetCollection.getInstance().addSQLResultSet(
                              (SQLResultSetResults) results);
                        }
                      } catch (SQLException e) {
                        ExceptionDisplayDialog.openError(fWindow.getShell(), null, null, e);
                      }

                      //											tableView
                      //													.loadTable(entityFactory
                      //															.create(
                      //																	bookmark,
                      //																	null,
                      //																	(String) locations[i],
                      //																	Entity.TABLE_TYPE));
                    }

                  }
                }
              }
            }
          } catch (NotConnectedException e) {
            // ignore this - not mission critical
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
      }
    }
  }

}