package net.sourceforge.phpdt.sql;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

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

import org.apache.crimson.tree.XmlDocument;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
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.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import net.sourceforge.phpdt.sql.view.bookmark.BookmarkContentProvider;
import net.sourceforge.phpdt.sql.view.bookmark.SubsetContentProvider;

/**
 * @author 
 */
public class PHPEclipseSQLPlugin
extends AbstractUIPlugin
implements IConstants {

	private static PHPEclipseSQLPlugin plugin;
	public final static String PLUGIN_ID = "net.sourceforge.phpeclipse.sql";

	public PHPEclipseSQLPlugin(IPluginDescriptor descriptor) {
		super(descriptor);
		plugin = this;
	}

	public static PHPEclipseSQLPlugin getDefault() {
		return plugin;
	}
	/**
	 * Reads the PHPEclipseSQL 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("ext")) { //$NON-NLS-1$
			// It's the 2.0 format for preferences
			BookmarkContentProvider.getInstance().load(target);
		} else {
			//It's the 2.1 format for preferences and subsets
			XmlDocument doc = new XmlDocument();
			FileInputStream source = null;
			try {
				source = new FileInputStream(target);
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
				return;
			}
			DocumentBuilderFactory factory =
			DocumentBuilderFactory.newInstance();
			DocumentBuilder parser;
			try {
				parser = factory.newDocumentBuilder();
				doc = (XmlDocument) parser.parse(source);
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
				return;
			} catch (SAXException e) {
				e.printStackTrace();
				return;
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
			Element root = doc.getDocumentElement();
			BookmarkContentProvider.getInstance().importXML(root);
			SubsetContentProvider.getInstance().importXML(root);
		}
	}

	public void startup() throws CoreException {
		super.startup();
		ISaveParticipant saveParticipant = new PHPSQLSaveParticipant();
		ISavedState lastState =
		ResourcesPlugin.getWorkspace().addSaveParticipant(
														 this,
														 saveParticipant);
		if (lastState == null)
			return;
		IPath location = lastState.lookup(new Path("save"));
		if (location == null)
			return;
		// the plugin instance should read any important state from the file. 
		File f = getStateLocation().append(location).toFile();
		readStateFrom(f);
	}

	protected void writeImportantState(File target) {
		XmlDocument doc = new XmlDocument();
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(target);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
			return;
		}
		Element root = (Element) doc.appendChild(doc.createElement(Messages.getString("ExportXMLAction.SavedData"))); //$NON-NLS-1$

		BookmarkContentProvider.getInstance().exportXML(root);
		SubsetContentProvider.getInstance().exportXML(root);

		try {
			doc.write(out);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 *  Gets an image descriptof from a file in the icons directory 
	 * @param name of the file to get
	 * @return ImageDescriptor or null if not found
	 */
	public static ImageDescriptor getImageDescriptor(String name) {
		ImageDescriptor descriptor = null;
		try {
			URL installURL =
			PHPEclipseSQLPlugin
			.getDefault()
			.getDescriptor()
			.getInstallURL();
			URL url = new URL(installURL, "icons/" + name);
			descriptor = ImageDescriptor.createFromURL(url);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return descriptor;
	}
	public static Image getImage(String name) {
		return getImageDescriptor(name).createImage();
	}

	public void dispose() throws CoreException {
	}

	protected void initializeDefaultPluginPreferences() {
		RGB BACKGROUND = new RGB(255, 255, 255);
		RGB COMMENT = new RGB(88, 148, 64);
		RGB KEYWORD = new RGB(126, 0, 75);
		RGB STRING = new RGB(0, 0, 255);
		RGB NUMERIC = new RGB(255, 0, 0);
		RGB DEFAULT = new RGB(0, 0, 0);
		IPreferenceStore store = getPreferenceStore();
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.background.color",
									  BACKGROUND);
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.text.color",
									  DEFAULT);
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.keyword.color",
									  KEYWORD);
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.comment.color",
									  COMMENT);
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.string.color",
									  STRING);
		PreferenceConverter.setDefault(
									  store,
									  "phpeclipse.sql.numeric.color",
									  NUMERIC);
		getPreferenceStore().setDefault("phpeclipse.sql.text.bold", false);
		getPreferenceStore().setDefault("phpeclipse.sql.keyword.bold", true);
		getPreferenceStore().setDefault("phpeclipse.sql.string.bold", false);
		getPreferenceStore().setDefault("phpeclipse.sql.comment.bold", false);
		getPreferenceStore().setDefault("phpeclipse.sql.numeric.bold", false);
		PreferenceConverter.setDefault(getPreferenceStore(), "phpeclipsesql.font", (FontData) null); //$NON-NLS-1$
	}

	public boolean showView(String view) {
		IWorkbench workbench = getWorkbench();
		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
		IWorkbenchPage page = window.getActivePage();
		IViewPart viewPart = null;
		try {
			viewPart = page.showView(view);
		} catch (PartInitException e) {
			e.printStackTrace();
			return false;
		}

		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/test");

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

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

		getPreferenceStore().setDefault(
									   "phpeclipse.sql.filename.connect",
									   "C:\\apache\\mysql\\lib\\mysql-connector-java-2.0.14-bin.jar");

		PreferenceConverter.setDefault(
									  getPreferenceStore(),
									  "phpeclipse.sql.font",
									  (FontData) null);
		return(viewPart != null);
	}

}
class PHPSQLSaveParticipant implements ISaveParticipant, IConstants {
	/**
	 * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(ISaveContext)
	 */
	public void doneSaving(ISaveContext context) {
	}

	/**
	 * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(ISaveContext)
	 */
	public void prepareToSave(ISaveContext context) throws CoreException {
	}

	/**
	 * @see org.eclipse.core.resources.ISaveParticipant#rollback(ISaveContext)
	 */
	public void rollback(ISaveContext context) {
	}

	/**
	 * @see org.eclipse.core.resources.ISaveParticipant#saving(ISaveContext)
	 */
	public void saving(ISaveContext context) throws CoreException {
		switch (context.getKind()) {
		case ISaveContext.FULL_SAVE :
			PHPEclipseSQLPlugin sqlPluginInstance =
			PHPEclipseSQLPlugin.getDefault();
			// save the plug in state 
			if (BookmarkContentProvider.getInstance().hasChanged()) {
				int saveNumber = context.getSaveNumber();
				String saveFileName =
				"save " + Integer.toString(saveNumber);
				File f =
				sqlPluginInstance
				.getStateLocation()
				.append(saveFileName)
				.toFile();
				// if we fail to write, an exception is thrown and we do not update the path 
				sqlPluginInstance.writeImportantState(f);
				context.map(new Path("save"), new Path(saveFileName));
				context.needSaveNumber();
			} else {
				if (DEBUG) {
					System.out.println("Not saving unchanged bookmarks");
				}
			}
			break;
		case ISaveContext.PROJECT_SAVE :
			// get the project related to this save operation 
			//IProject project = context.getProject(); 
			// save its information, if necessary 
			break;
		case ISaveContext.SNAPSHOT :
			// This operation needs to be really fast because 
			// snapshots can be requested frequently by the 
			// workspace. 
			break;
		}
	}
}