/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsd.ui.internal;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.wst.sse.core.IModelManager;
import org.eclipse.wst.sse.core.IModelManagerPlugin;


public class XSDEditorPlugin extends AbstractUIPlugin
{
  public final static String PLUGIN_ID = "org.eclipse.wst.xsd.ui";
  public final static String XSD_EDITOR_ID = "org.eclipse.wst.xsd.ui.XSDEditor";
  
  public final static String DEFAULT_TARGET_NAMESPACE = "http://www.example.org";
  
  protected static XSDEditorPlugin plugin;
  //  protected XMLSchemaPackage xmlschemaPackage;
// KCPort private static MsgLogger myMsgLogger;
 
  public XSDEditorPlugin(IPluginDescriptor descriptor) 
  {
    super(descriptor);
    plugin = this;
// KCPort    myMsgLogger = getMsgLogger();
    //myMsgLogger.write(Level.CONFIG, new BuildInfo());
    //myMsgLogger.write(Level.CONFIG, BuildInfo.getWSABuildLevel());
  }

  /**
   * Copy the w3c XMLSchema.dtd and datatypes.dtd into the plugin metadata directory
   * for validation purposes
   */
  public void startup()
  {
    modelManager = getModelManager();
  }

  private static IModelManager modelManager;

  public static IModelManager getModelManager() {
    IModelManagerPlugin plugin = (IModelManagerPlugin) Platform.getPlugin(IModelManagerPlugin.ID);
    return plugin.getModelManager();
  }
  
  
  /**
   * Get the Install URL
   */
  public static URL getInstallURL()
  {
    return getPlugin().getDescriptor().getInstallURL();
  }

  /**
   * Return the plugin physical directory location
   */
  public static IPath getPluginLocation()
  {
    try 
    {
      IPath installPath = new Path(getInstallURL().toExternalForm()).removeTrailingSeparator();
      String installStr = Platform.asLocalURL(new URL(installPath.toString())).getFile();
      return new Path(installStr);
    } 
    catch (IOException e) 
    {

    }
    return null;
  }

  /**
   * Get the metadata directory for this plugin
   */
  public static String getMetaDataDirectory()
  {
    return getPlugin().getStateLocation().toOSString();
  }

  /** 
   *  Get the one xmlschema package.
   */
//   public XMLSchemaPackage getXMLSchemaPackage()
//   {
//     return xmlschemaPackage;
//   }

//   /** 
//    *  Get the one xmlschema factory.
//    */
//   public XMLSchemaFactory getXMLSchemaFactory()
//   {
//     return (XMLSchemaFactory)xmlschemaPackage.getEFactoryInstance();
//   }

  /**
   * Get the singleton instance.
   */
  public static XSDEditorPlugin getPlugin()
  {
    return plugin;
  }

  public static Image getXSDImage(String iconName)
  {
    return getPlugin().getImage(iconName);
  }

  public Image getImage(String iconName)
  {
    ImageRegistry imageRegistry = getImageRegistry();
    
    if (imageRegistry.get(iconName) != null)
    {
      return imageRegistry.get(iconName);
    }
    else
    {
      imageRegistry.put(iconName, ImageDescriptor.createFromFile(getClass(), iconName));
      return imageRegistry.get(iconName);
    }
  }
  
  public static String getXSDString(String key)
  {
    return Platform.getResourceBundle(plugin.getBundle()).getString(key);
  }

	/**
	 * This gets the string resource and does one substitution.
	 */
	public String getString(String key, Object s1)
	{
	  return MessageFormat.format(Platform.getResourceBundle(getBundle()).getString(key), new Object [] { s1 });
	}

//  public IWorkspace getWorkspace()
//  {
//    return ResourcesPlugin.getWorkspace();
//  }

  public static Shell getShell() 
  {	
    return getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell();
  }

  /**
   * Get the xml schema default namespace prefix
   */
  public String getXMLSchemaPrefix()
  {
    return getPreferenceStore().getString(CONST_XSD_DEFAULT_PREFIX_TEXT);
  }
  
  /**
   * Get the xml schema default target namespace
   */
  public String getXMLSchemaTargetNamespace()
  {
  	String targetNamespace = getPreferenceStore().getString(CONST_DEFAULT_TARGET_NAMESPACE);
    if(!targetNamespace.endsWith("/")){
    	targetNamespace = targetNamespace + "/";
    }
    return targetNamespace;
  }

  /**
   * Get the xml schema language qualification
   */
  public boolean isQualifyXMLSchemaLanguage()
  {
    return getPreferenceStore().getBoolean(CONST_XSD_LANGUAGE_QUALIFY);
  }
  
  /**
   * Method isCombinedDesignAndSourceView.
   * @return boolean if the editor should have a single page that is
   * a combined design and source page
   */
  public boolean isCombinedDesignAndSourceView()
  {
    return COMBINED_LAYOUT.equals(getPreferenceStore().getString(EDITOR_LAYOUT));
  }

  public int getDesignLayout()
  {
    if (TOP_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
       return SWT.VERTICAL;
    }
    else if (BOTTOM_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return SWT.VERTICAL;
    }
    else if (LEFT_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return SWT.HORIZONTAL;
    }
    else if (RIGHT_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return SWT.HORIZONTAL;
    }
    return SWT.HORIZONTAL;      
  }

  public String getDesignLayoutPosition()
  {
    if (TOP_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
       return TOP_LAYOUT;
    }
    else if (BOTTOM_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return BOTTOM_LAYOUT;
    }
    else if (LEFT_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return LEFT_LAYOUT;
    }
    else if (RIGHT_LAYOUT.equals(getPreferenceStore().getString(DESIGN_LAYOUT)))
    {
      return RIGHT_LAYOUT;
    }
    return RIGHT_LAYOUT;      
  }

  /*---------------------------------------------------------------------------*/
  /* the following methods are impls for the IPluginHelper interface           */
  /*---------------------------------------------------------------------------*/
//  public void setMsgLoggerConfig(Hashtable msgLoggerConfig)
//  {
//    getMsgLogger().setMsgLoggerConfig(msgLoggerConfig);
//  }
//
//  public Hashtable getMsgLoggerConfig(Plugin plugin)
//  {
//    return (new PluginHelperImpl().getMsgLoggerConfig(plugin));
//  }
//
//  public Hashtable getMsgLoggerConfig()
//  {
//    return (getMsgLoggerConfig(this));
//  }
//
//  /**
//   * XSDEditor and XSDModel use the same logger.  See plugin.xml
//   */
//  public MsgLogger getMsgLogger()
//  {
//    if (myMsgLogger == null)
//    {
//      myMsgLogger = (MsgLogger) MsgLogger.getFactory().getLogger(new PluginHelperImpl().getMsgLoggerName(this), this);
//    }
//    return (myMsgLogger);
//  }
  
  public static final String CONST_XSD_DEFAULT_PREFIX_TEXT = "org.eclipse.wst.xmlschema.xsdDefaultPrefixText";
  public static final String CONST_XSD_LANGUAGE_QUALIFY = "org.eclipse.wst.xmlschema.xsdQualify";
  public static final String CONST_DEFAULT_TARGET_NAMESPACE = "org.eclipse.wst.xmlschema.defaultTargetnamespaceText";

  // Preference to store which page should come up as the default page in the editor.  This setting is based
  // on the page that was left showing the last time the editor was closed.
  public static String DEFAULT_PAGE = "org.eclipse.wst.xsd.ui.internal.defaultPage";
  public static String DESIGN_PAGE = "org.eclipse.wst.xsd.ui.internal.designPage";
  public static String SOURCE_PAGE = "org.eclipse.wst.xsd.ui.internal.sourcePage";
  public static String GRAPH_PAGE = "org.eclipse.wst.xsd.ui.internal.graphPage";
  
  public static String EDITOR_LAYOUT = "org.eclipse.wst.xsd.ui.internal.editorlayout";
  public static String COMBINED_LAYOUT = "org.eclipse.wst.xsd.ui.internal.combined";
  public static String SEPARATE_LAYOUT = "org.eclipse.wst.xsd.ui.internal.separate";

  public static String DESIGN_LAYOUT = "org.eclipse.wst.xsd.ui.internal.designlayout";
  public static String TOP_LAYOUT = "org.eclipse.wst.xsd.ui.internal.top";
  public static String BOTTOM_LAYOUT = "org.eclipse.wst.xsd.ui.internal.bottom";
  public static String LEFT_LAYOUT = "org.eclipse.wst.xsd.ui.internal.left";
  public static String RIGHT_LAYOUT = "org.eclipse.wst.xsd.ui.internal.right";
  
  /**
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeDefaultPreferences(IPreferenceStore)
   */
  protected void initializeDefaultPreferences(IPreferenceStore store)
  {
    super.initializeDefaultPreferences(store);

    store.setDefault(CONST_XSD_DEFAULT_PREFIX_TEXT, "xsd");
    store.setDefault(CONST_XSD_LANGUAGE_QUALIFY, false);

    store.setDefault(DEFAULT_PAGE, DESIGN_PAGE);
    store.setDefault(EDITOR_LAYOUT, COMBINED_LAYOUT);
    store.setDefault(DESIGN_LAYOUT, RIGHT_LAYOUT);
    
    store.setDefault(XSDEditorPlugin.CONST_DEFAULT_TARGET_NAMESPACE, DEFAULT_TARGET_NAMESPACE);
  }
  
  public void setDefaultPage(String page)
  {
    getPreferenceStore().setValue(DEFAULT_PAGE, page);
  }
  
  /**
   * Method getDefaultPage.
   * @return String value of the string constant that is the default page the editor should turn to when
   * first opened.  Changes to the last visible page when the editor was closed
   */
  public String getDefaultPage()
  {
    return getPreferenceStore().getString(DEFAULT_PAGE);
  }    

  protected URL baseURL;
  public URL getBaseURL()
  {
    return getDescriptor().getInstallURL();
  }

  public Image getIconImage(String object)
  {
    try
    {
      return ExtendedImageRegistry.getInstance().getImage(new URL(getBaseURL() + "icons/" + object + ".gif"));
    }
    catch (MalformedURLException exception)
    {
      System.out.println("Failed to load image for '" + object + "'");
    }
    return null;
  }
}
