/*******************************************************************************
 * 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.properties.section;

import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.wst.common.ui.internal.viewers.ResourceFilter;
import org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertyConstants;
import org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetWidgetFactory;
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.refactor.delete.XSDExternalFileCleanup;
import org.eclipse.wst.xsd.ui.internal.util.TypesHelper;
import org.eclipse.wst.xsd.ui.internal.util.XSDSchemaHelper;
import org.eclipse.wst.xsd.ui.internal.wizards.XSDSelectIncludeFileWizard;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.impl.XSDImportImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Element;

public class NamespaceAndSchemaLocationSection extends CommonDirectivesSection
{
	Text namespaceText, prefixText;
  protected String oldPrefixValue;
	  
	public NamespaceAndSchemaLocationSection()
  {
		super();
	}
	
	/**
	 * @see org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.wst.common.ui.properties.internal.provisional.TabbedPropertySheetWidgetFactory)
	 */
	public void createControls(Composite parent, TabbedPropertySheetWidgetFactory factory)
	{
		super.createControls(parent, factory);
		Composite composite = getWidgetFactory().createFlatFormComposite(parent);

		CLabel namespaceLabel = getWidgetFactory().createCLabel(composite, XSDEditorPlugin.getXSDString("_UI_LABEL_NAMESPACE")); //$NON-NLS-1$
    namespaceText = getWidgetFactory().createText(composite, "", SWT.NONE); //$NON-NLS-1$
		namespaceText.setEditable(false);

    FormData data = new FormData();
    data.left = new FormAttachment(0, 0);
    data.right = new FormAttachment(namespaceText, +ITabbedPropertyConstants.HSPACE);
    data.top = new FormAttachment(namespaceText, 0, SWT.CENTER);
    namespaceLabel.setLayoutData(data);
    
    data = new FormData();
    data.left = new FormAttachment(0, 110);
    data.right = new FormAttachment(100, -rightMarginSpace - ITabbedPropertyConstants.HSPACE);
    data.top = new FormAttachment(0, 0);
    namespaceText.setLayoutData(data);
    
		CLabel prefixLabel = getWidgetFactory().createCLabel(composite, XSDEditorPlugin.getXSDString("_UI_LABEL_PREFIX")); //$NON-NLS-1$				
		prefixText = getWidgetFactory().createText(composite, "", SWT.NONE); //$NON-NLS-1$
		prefixText.setEditable(true);
    prefixText.addListener(SWT.Modify, this);

    data = new FormData();
    data.left = new FormAttachment(0, 0);
    data.right = new FormAttachment(prefixText, 0);
    data.top = new FormAttachment(prefixText, 0, SWT.CENTER);
    prefixLabel.setLayoutData(data);  
    
		data = new FormData();
		data.left = new FormAttachment(0, 110);
		data.right = new FormAttachment(100, -rightMarginSpace - ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(namespaceText, +ITabbedPropertyConstants.VSPACE);
		prefixText.setLayoutData(data);
   
		// Create Schema Location Label
		CLabel schemaLocationLabel = getWidgetFactory().createCLabel(composite, XSDEditorPlugin.getXSDString("_UI_LABEL_SCHEMA_LOCATION")); //$NON-NLS-1$
    schemaLocationText = getWidgetFactory().createText(composite, "", SWT.NONE); //$NON-NLS-1$

		// Create Wizard Button
		wizardButton = getWidgetFactory().createButton(composite, "", SWT.NONE); //$NON-NLS-1$
    wizardButton.setImage(XSDEditorPlugin.getXSDImage("icons/browsebutton.gif")); //$NON-NLS-1$
		FormData buttonFormData = new FormData();
		buttonFormData.left = new FormAttachment(100, -rightMarginSpace + 2);
		buttonFormData.right = new FormAttachment(100, 0);
		buttonFormData.top = new FormAttachment(schemaLocationText, 0, SWT.CENTER);
		wizardButton.setLayoutData(buttonFormData);
		wizardButton.addSelectionListener(this);
		
		// Create Schema Location Text
		schemaLocationText.setEditable(true);
		FormData schemaLocationData = new FormData();
		schemaLocationData.left = new FormAttachment(0, 110);
		schemaLocationData.right = new FormAttachment(wizardButton, 0);
		schemaLocationData.top = new FormAttachment(prefixText, +ITabbedPropertyConstants.VSPACE);
		schemaLocationText.setLayoutData(schemaLocationData);
		schemaLocationText.addListener(SWT.Modify, this);
    
    data = new FormData();
    data.left = new FormAttachment(0, 0);
    data.right = new FormAttachment(schemaLocationText, 0);
    data.top = new FormAttachment(schemaLocationText, 0, SWT.CENTER);
    schemaLocationLabel.setLayoutData(data);
    
    // error text
    errorText = new StyledText(composite, SWT.FLAT);
    errorText.setEditable(false);
    errorText.setEnabled(false);
    errorText.setText("");
    
    data = new FormData();
    data.left = new FormAttachment(schemaLocationText, 0, SWT.LEFT);
    data.right = new FormAttachment(100, 0);
    data.top = new FormAttachment(schemaLocationText, 0);
    errorText.setLayoutData(data);
  }
	
	public void widgetSelected(SelectionEvent event)
  {
		if (event.widget == wizardButton)
    {
      setListenerEnabled(false);
			Shell shell = Display.getCurrent().getActiveShell();
		    
			IFile currentIFile = ((IFileEditorInput)getActiveEditor().getEditorInput()).getFile();
			ViewerFilter filter = new ResourceFilter(new String[] { ".xsd" }, //$NON-NLS-1$ 
		            new IFile[] { currentIFile },
		            null);
		      
			XSDSelectIncludeFileWizard fileSelectWizard = 
			   new XSDSelectIncludeFileWizard(xsdSchema, 
                                        false,
			                                  XSDEditorPlugin.getXSDString("_UI_FILEDIALOG_SELECT_XML_SCHEMA"), //$NON-NLS-1$
			                                  XSDEditorPlugin.getXSDString("_UI_FILEDIALOG_SELECT_XML_DESC"), //$NON-NLS-1$
			                                  filter,
			                                  (IStructuredSelection) selection);

			WizardDialog wizardDialog = new WizardDialog(shell, fileSelectWizard);
			wizardDialog.create();
			wizardDialog.setBlockOnOpen(true);
			int result = wizardDialog.open();
			  
		  String value = schemaLocationText.getText();
      prefixText.removeListener(SWT.Modify, this);
		  if (result == Window.OK)
		  {
        errorText.setText("");
        IFile selectedIFile = fileSelectWizard.getResultFile();
        String schemaFileString = value;
        if (selectedIFile != null) 
        {
          schemaFileString = URIHelper.getRelativeURI(selectedIFile.getLocation(), currentIFile.getLocation());
        }
        else
        {
          schemaFileString = fileSelectWizard.getURL();
        }

        String namespace = fileSelectWizard.getNamespace();
        if (namespace == null) namespace = "";

        XSDSchema externalSchema = fileSelectWizard.getExternalSchema();
        handleSchemaLocationChange(schemaFileString, namespace, externalSchema);
		  }
      setListenerEnabled(true);
      prefixText.addListener(SWT.Modify, this);
		}
	}

  protected void handleSchemaLocationChange(String schemaFileString, String namespace, XSDSchema externalSchema)
  {
    XSDConcreteComponent comp = (XSDConcreteComponent)getInput();
    if (comp instanceof XSDImport)
    {
      XSDImport xsdImport = (XSDImport)comp;
      Element importElement = comp.getElement();
      
      beginRecording(XSDEditorPlugin.getXSDString("_UI_IMPORT_CHANGE"), importElement);

      xsdImport.setNamespace(namespace);
      xsdImport.setSchemaLocation(schemaFileString);
      xsdImport.setResolvedSchema(externalSchema);
      
      java.util.Map map = xsdSchema.getQNamePrefixToNamespaceMap();
      
//      System.out.println("changed Import Map is " + map.values());
//      System.out.println("changed import Map keys are " + map.keySet());

      // Referential integrity on old import
      // How can we be sure that if the newlocation is the same as the oldlocation
      // the file hasn't changed
      
      XSDSchema referencedSchema = xsdImport.getResolvedSchema();
      if (referencedSchema != null)
      {
        XSDExternalFileCleanup cleanHelper = new XSDExternalFileCleanup(referencedSchema);
        cleanHelper.visitSchema(xsdSchema);
      }

      Element schemaElement = getSchema().getElement();

      // update the xmlns in the schema element first, and then update the import element next
      // so that the last change will be in the import element.  This keeps the selection
      // on the import element
      TypesHelper helper = new TypesHelper(externalSchema);
      String prefix = helper.getPrefix(namespace, false);
      
      if (map.containsKey(prefix))
      {
        prefix = null;
      }

      if (prefix == null || (prefix !=null && prefix.length() == 0))
      {
        StringBuffer newPrefix = new StringBuffer("pref");  //$NON-NLS-1$
        int prefixExtension = 1;
        while (map.containsKey(newPrefix.toString()) && prefixExtension < 100)
        {
          newPrefix = new StringBuffer("pref" + String.valueOf(prefixExtension));
          prefixExtension++;
        }
        prefix = newPrefix.toString();
      }

      if (namespace.length() > 0)
      {
        // if ns already in map, use its corresponding prefix
        if (map.containsValue(namespace))
        {
          TypesHelper typesHelper = new TypesHelper(xsdSchema);
          prefix = typesHelper.getPrefix(namespace, false);
        }
        else // otherwise add to the map
        {
          schemaElement.setAttribute("xmlns:"+prefix, namespace);
        }
        prefixText.setText(prefix);
      }
      else
      {
        prefixText.setText("");
        namespaceText.setText("");
      }
        
      endRecording(importElement);
      
//      System.out.println("changed Import Map is " + map.values());
//      System.out.println("changed import Map keys are " + map.keySet());

    }        
    refresh();
  }
  
	/*
	 * @see org.eclipse.wst.common.ui.properties.internal.provisional.view.ITabbedPropertySection#refresh()
	 */
	public void refresh()
	{
		if (doRefresh)
		{
      errorText.setText("");
			setListenerEnabled(false);

			Element element = null;
			if (input instanceof XSDImport) { 
				element = ((XSDImportImpl) input).getElement();
				
				String namespace = element.getAttribute("namespace"); //$NON-NLS-1$
				String schemaLocation = element.getAttribute("schemaLocation"); //$NON-NLS-1$
				
				TypesHelper helper = new TypesHelper(xsdSchema);
		        String prefix = helper.getPrefix(element.getAttribute(XSDConstants.NAMESPACE_ATTRIBUTE), false);

				if (namespace == null) {
					namespace = ""; //$NON-NLS-1$
				}
				if (prefix == null) {
					prefix = ""; //$NON-NLS-1$
				}
				if (schemaLocation == null) {
					schemaLocation = ""; //$NON-NLS-1$
				}
				
				namespaceText.setText(namespace);
				prefixText.setText(prefix);
				schemaLocationText.setText(schemaLocation);
        oldPrefixValue = prefixText.getText();
			}

			setListenerEnabled(true);
		}
	}

  /* (non-Javadoc)
   * @see org.eclipse.wst.common.ui.properties.internal.provisional.ISection#shouldUseExtraSpace()
   */
  public boolean shouldUseExtraSpace()
  {
    return true;
  }

  public void doHandleEvent(Event event)
  {
    super.doHandleEvent(event);
    if (event.type == SWT.Modify)
    {
      if (event.widget == prefixText)
      {
        if (validatePrefix(prefixText.getText()) && schemaLocationText.getText().trim().length() > 0)
        {
          Element element = ((XSDConcreteComponent)getInput()).getElement();
          Map map = getSchema().getQNamePrefixToNamespaceMap();

          if (map.containsKey(prefixText.getText()))
          {
            setErrorMessage(XSDEditorPlugin.getXSDString("_ERROR_LABEL_PREFIX_EXISTS"));
          }
          else
          {
            beginRecording(XSDEditorPlugin.getXSDString("_UI_PREFIX_CHANGE"), element);
            
            Element schemaElement = getSchema().getElement();
            schemaElement.removeAttribute("xmlns:"+oldPrefixValue);
            schemaElement.setAttribute("xmlns:" + prefixText.getText(), namespaceText.getText());
            XSDSchemaHelper.updateElement(getSchema());

            clearErrorMessage();
            oldPrefixValue = prefixText.getText();
            endRecording(element);  

//            System.out.println("Map is " + map.values());
//            System.out.println("Map keys are " + map.keySet());
          }
        }
      }
    }
  }
}
