/*******************************************************************************
 * 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.rename.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());
          }
        }
      }
    }
  }
}
