package com.quantum;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.resources.ISavedState;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.quantum.model.BookmarkCollection;
import com.quantum.util.xml.XMLHelper;
import com.quantum.view.subset.SubsetContentProvider;

/**
 * Main class of the quantum plugin, sets defaults, saves and recovers state.
 * @author root
 */
public class QuantumPlugin extends AbstractUIPlugin {
    public final static String PLUGIN_ID = "net.sourceforge.phpeclipse.quantum.sql"; 
	private static QuantumPlugin plugin;
	private Clipboard sysClip;

	/**
	 * 
	 * TODO: BCH - this constructor has changed in Eclipse 3.0.  This
	 * old version of the constructor is still necessary for running under
	 * Eclipse 2.x.
	 * 
	 * @param descriptor
	 */
	public QuantumPlugin(IPluginDescriptor descriptor) {
		this();
	}
	/**
	 * This version is recommended for eclipse3.0 and above
	 */
	public QuantumPlugin(){ 
		super();
		plugin = this;
	}

	public static QuantumPlugin getDefault() {
		return plugin;
	}
	/**
	 * Reads the Quantum Plugin state from a file. The file has been created with writeImportantState
	 * @param target
	 */
	protected void readStateFrom(File target) {
		String fileName = target.getName();
		if (!fileName.endsWith(Messages.getString("QuantumPlugin.saveFileExtension"))){ //$NON-NLS-1$
            try {
    			// It's the 2.0 format for preferences
    			BookmarkCollection.getInstance().load(target);
            } catch (IOException e) {
                e.printStackTrace();
            }
		} else {
			//It's the 2.1 format for preferences and subsets
			FileInputStream source = null;
			try {
				source = new FileInputStream(target);
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
				return;
			}
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder parser;
			try {
				parser = factory.newDocumentBuilder();
                Document doc = parser.parse(source);

                Element root = doc.getDocumentElement();
                BookmarkCollection.getInstance().importXML(root);
                BookmarkCollection.getInstance().setChanged(false);
                SubsetContentProvider.getInstance().importXML(root);

			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.Plugin#startup()
	 * This method is deprecated in Eclipse3.0 we must use start(BundleContext context): 
	 * Migration completed.
	 */
	public void startup() throws CoreException {
		super.startup();
		startupMigrationTempMethod(); // To be removed later
 	}
	
	/**
	 * Used during startup Eclipse3.0 compatible
	 */
	public void start(BundleContext bundleContext) throws Exception {
		super.start(bundleContext); 
		startupMigrationTempMethod(); // To be removed later
	}
	private void startupMigrationTempMethod() throws CoreException {
		// the contents of this.startup() is moved to here to avoid code duplication - see this.start(BundleContext) 
		ISavedState lastState =
			ResourcesPlugin.getWorkspace().addSaveParticipant(
				this,
				new QuantumSaveParticipant());
		if (lastState != null) {
    		IPath location = lastState.lookup(new Path(Messages.getString("QuantumPlugin.saveDir"))); //$NON-NLS-1$
    		if (location != null) {
        		// the plugin instance should read any important state from the file. 
        		File f = getStateLocation().append(location).toFile();
        		readStateFrom(f);
        		
            }
        }
        sysClip = new Clipboard(null);
 	}

    
	/**
	 * Write the bookmarks and subsets to a file, saving them for next use of the quantum plugin
	 * @param target
	 */
	protected void writeImportantState(File target) {
        try {
            Document document = XMLHelper.createEmptyDocument();
            
    		Element root = (Element) document.appendChild(
                document.createElement(Messages.getString("ExportXMLAction.SavedData"))); //$NON-NLS-1$
    		
    		BookmarkCollection.getInstance().exportXML(root);
    		SubsetContentProvider.getInstance().exportXML(root);

            FileWriter writer =  new FileWriter(target);
            try {
                XMLHelper.write(writer, document);
    		} finally {
    			writer.close();
    		}
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	protected void initializeDefaultPluginPreferences() {
		PluginPreferences.initialize(getPreferenceStore());
		
		getPreferenceStore().setDefault(
            "phpeclipse.sql.select.template",
            "$results = mysql_query(\"SELECT {0} FROM {1} WHERE {2} \");");

          getPreferenceStore().setDefault(
            "phpeclipse.sql.insert.template",
            "$results = mysql_query(\"INSERT INTO {0} ({1}) VALUES {2} \");");

          getPreferenceStore().setDefault("phpeclipse.sql.update.template", "$results = mysql_query(\"UPDATE {0} SET {1} WHERE {2} \");");

          getPreferenceStore().setDefault("phpeclipse.sql.delete.template", "$results = mysql_query(\"DELETE FROM {0} WHERE {1} \");");

          getPreferenceStore().setDefault("phpeclipse.sql.username.connect", "root");

          getPreferenceStore().setDefault("phpeclipse.sql.connect.connect", "jdbc:mysql://localhost/mysql");

          getPreferenceStore().setDefault("phpeclipse.sql.driver.connect", "com.mysql.jdbc.Driver");

          getPreferenceStore().setDefault("phpeclipse.sql.type.connect", "MySQL");

          getPreferenceStore().setDefault(
            "phpeclipse.sql.filename.connect",
            "C:\\wampp2\\mysql\\lib\\mysql-connector.jar");
	}
	// Returns the active page
	public IWorkbenchPage getActivePage()
	{
		IWorkbench workbench = getWorkbench();
		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
		if (window == null)	return null;
		IWorkbenchPage page = window.getActivePage();
		return page;
	}
	/**
	 * returns a view in the active page, creating it if needed
	 * @param view, the name of the view (e.g com.quantum.view.tableview)
	 * @return true if successful, false if not
	 */
	public IViewPart getView(String view)
	{
		IViewPart tableView = null;
		try {
			IWorkbenchPage page = QuantumPlugin.getDefault().getActivePage();
			tableView =  page.findView(view);
			if (tableView == null){
				// showView will give focus to the created view, we don't want that
				// so we save the active part
				IWorkbenchPart part = page.getActivePart();
				tableView = page.showView(view);
				// and return the focus to it
				page.activate(part);
			}
		} catch (PartInitException e) {
			e.printStackTrace();
		}
		return tableView;
	}



	/**
	 * @return
	 */
	public Clipboard getSysClip() {
		return sysClip;
	}
	protected void initializeImageRegistry(ImageRegistry registry) {
		super.initializeImageRegistry(registry);
		try {
			ImageStore.initialize(this, registry, getIconLocation());
		} catch (MalformedURLException e) {
			// this should never happen, but if it does, we don't get images.
		}
	}

	/**
	 * @return
	 * @throws MalformedURLException
	 */
	private URL getIconLocation() throws MalformedURLException {
//		URL installURL = getDescriptor().getInstallURL();
		URL installURL = getBundle().getEntry("/");
		return new URL(installURL, "icons/");
	}
}