/*******************************************************************************
 * 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;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.eclipse.wst.xml.core.internal.document.DocumentImpl;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.refactor.rename.TargetNamespaceChangeHandler;
import org.eclipse.wst.xsd.ui.internal.util.TypesHelper;
import org.eclipse.wst.xsd.ui.internal.util.XSDSchemaHelper;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SchemaPropertySource
  extends BasePropertySource
  implements IPropertySource
{
  private String oldPrefix = "";
  private String oldNamespace = "";
  
  private String[] attributeFormDefaultComboValues =
  { 
    "",
    XSDEditorPlugin.getXSDString("_UI_COMBO_UNQUALIFIED"),
    XSDEditorPlugin.getXSDString("_UI_COMBO_QUALIFIED")
  };
  
  private String[] elementFormDefaultComboValues =
  {
    "",
    XSDEditorPlugin.getXSDString("_UI_COMBO_UNQUALIFIED"),
    XSDEditorPlugin.getXSDString("_UI_COMBO_QUALIFIED")
  };

  private String[] blockDefaultComboValues =
  {
    "",
    "#all",
    "extension",
    "restriction",
    "substitution"
  };

  private String[] finalDefaultComboValues =
  {
    "",
    "#all",
    "extension",
    "restriction"
  };
  
  /**
   * 
   */
  public SchemaPropertySource()
  {
    super();
  }
  /**
   * @param viewer
   * @param xsdSchema
   */
  public SchemaPropertySource(Viewer viewer, XSDSchema xsdSchema)
  {
    super(viewer, xsdSchema);
  }
  /**
   * @param xsdSchema
   */
  public SchemaPropertySource(XSDSchema xsdSchema)
  {
    super(xsdSchema);
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
   */
  public Object getEditableValue()
  {
    return null;
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
   */
  public IPropertyDescriptor[] getPropertyDescriptors()
  {
    List list = new ArrayList();
    // Create a descriptor and set a category
// These have been moved to the General tab    
//    PropertyDescriptor prefixDescriptor = 
//    new TextPropertyDescriptor(
//        "prefix",
//        "prefix");
//    list.add(prefixDescriptor);
//    prefixDescriptor.setCategory("Namespace");
//
//    PropertyDescriptor targetNamespaceDescriptor = 
//    new TextPropertyDescriptor(
//        XSDConstants.TARGETNAMESPACE_ATTRIBUTE,
//        XSDConstants.TARGETNAMESPACE_ATTRIBUTE);
//    list.add(targetNamespaceDescriptor);
//    targetNamespaceDescriptor.setCategory("Namespace");
    
    PropertyDescriptor versionDescriptor = 
    new TextPropertyDescriptor(
        XSDConstants.VERSION_ATTRIBUTE,
        XSDConstants.VERSION_ATTRIBUTE);
//    versionDescriptor.setDescription("Version attribute"); // XSDEditorPlugin.getXSDString("_UI_TOOLTIP_VERSION"));
    list.add(versionDescriptor);
    PropertyDescriptor xmlLangDescriptor = 
    new TextPropertyDescriptor(
        "xml:lang",
        "xml:lang");
    list.add(xmlLangDescriptor);
    
    XSDComboBoxPropertyDescriptor attributeFormDefaultDescriptor =
    new XSDComboBoxPropertyDescriptor(
        XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE,
        XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE,
        attributeFormDefaultComboValues);
    list.add(attributeFormDefaultDescriptor);
    
    
    XSDComboBoxPropertyDescriptor elementFormDefaultDescriptor =
    new XSDComboBoxPropertyDescriptor(
        XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE,
        XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE,
        elementFormDefaultComboValues);
    list.add(elementFormDefaultDescriptor);
    
    XSDComboBoxPropertyDescriptor blockDefaultDescriptor =
    new XSDComboBoxPropertyDescriptor(
        XSDConstants.BLOCKDEFAULT_ATTRIBUTE,
        XSDConstants.BLOCKDEFAULT_ATTRIBUTE,
        blockDefaultComboValues);
    list.add(blockDefaultDescriptor);
    XSDComboBoxPropertyDescriptor finalDefaultDescriptor =
    new XSDComboBoxPropertyDescriptor(
        XSDConstants.FINALDEFAULT_ATTRIBUTE,
        XSDConstants.FINALDEFAULT_ATTRIBUTE,
        finalDefaultComboValues);
    list.add(finalDefaultDescriptor);

    IPropertyDescriptor[] result = new IPropertyDescriptor[list.size()];
    list.toArray(result);
    return result;
    //    return propertyDescriptors;
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
   */
  public Object getPropertyValue(Object id)
  {
    Object result = null;
    if (id instanceof String)
    {
      result = element.getAttribute((String) id);
      String attributeName = (String)id;
      if (result == null)
      {
        result = "";
      }

      if (attributeName.equals("prefix"))
      {
        TypesHelper helper = new TypesHelper(xsdSchema);
        String aPrefix = helper.getPrefix(element.getAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE), false);
        // System.out.println("schema targetNS is " + xsdSchema.getTargetNamespace());
        if (aPrefix != null && aPrefix.length() > 0)
        {
          return aPrefix;
        }
        return "";        
      }
      else
      {
        return result;
      }
    }
    return "";
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
   */
  public boolean isPropertySet(Object id)
  {
    return false;
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
   */
  public void resetPropertyValue(Object id)
  {
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
   */
  public void setPropertyValue(Object id, Object value)
  {
    if (value == null)
    {
      value = "";
    }
    if (value instanceof String)
    {
      String newValue = (String)value;
      String attributeName = (String)id;
      if (attributeName.equals("prefix"))
      {
        updatePrefix(newValue); 
      }
      else if (attributeName.equals(XSDConstants.TARGETNAMESPACE_ATTRIBUTE))
      {
        updateTargetNamespace(newValue);
      }
      else if (attributeName.equals("xml:lang"))
      {
        validateLanguage(newValue);
        // return;  // we will accept the value even though it does not conform
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_LANG_CHANGE"), element);
      }
      else if (attributeName.equals(XSDConstants.VERSION_ATTRIBUTE))
      {
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_VERSION_CHANGE"), element);
      }
      else if (attributeName.equals(XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE))
      {
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_ATTRIBUTEFORMDEFAULT_CHANGE"), element);
      }
      else if (attributeName.equals(XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE))
      {
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_ELEMENTFORMDEFAULT_CHANGE"), element); 
      }
      else if (attributeName.equals(XSDConstants.BLOCKDEFAULT_ATTRIBUTE))
      {
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_BLOCKDEFAULT_CHANGE"), element); 
      }
      else if (attributeName.equals(XSDConstants.FINALDEFAULT_ATTRIBUTE))
      {
        beginRecording(XSDEditorPlugin.getXSDString("_UI_SCHEMA_FINALDEFAULT_CHANGE"), element);
      }

      if (!attributeName.equals("prefix") && !attributeName.equals(XSDConstants.TARGETNAMESPACE_ATTRIBUTE))
      {        
        if (newValue.equals(""))
        {
          element.removeAttribute(attributeName); 
        }
        else
        {
          element.setAttribute(attributeName, newValue);
        }
        endRecording(element);
      }
    }
    Runnable delayedUpdate = new Runnable()
    {
      public void run()
      {
        if (viewer != null)
        viewer.refresh();
      }
    };
    Display.getCurrent().asyncExec(delayedUpdate);
    
  }

  public void setInput(Element element)
  {
    super.setInput(element);
    
    oldNamespace = "";
    oldPrefix = "";
    
    if (element!= null)
    {
      String targetNamespace = element.getAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE);
      oldNamespace = targetNamespace;

      TypesHelper helper = new TypesHelper(xsdSchema);
      String aPrefix = helper.getPrefix(targetNamespace, false);
      if (aPrefix != null && aPrefix.length() > 0)
      {
        oldPrefix = aPrefix;
      }
    }
  }
  
  
  private void updatePrefix(String newPrefix)
  {
    updateNamespaceInfo(newPrefix, oldNamespace);  
  }
  
  private void updateTargetNamespace(String newTargetNamespace)
  {
    updateNamespaceInfo(oldPrefix, newTargetNamespace);
  }
  
  private void updateNamespaceInfo(String newPrefix, String newTargetNamespace)
  {
//    System.out.println("\nold Prefix is " + oldPrefix);
//    System.out.println("old NS is " + oldNamespace);
//    System.out.println("new Prefix is " + newPrefix);
//    System.out.println("new NS is " + newTargetNamespace);
    
    DocumentImpl doc = (DocumentImpl)element.getOwnerDocument();

    String modelTargetNamespace = xsdSchema.getTargetNamespace();
//    System.out.println("Model TargetNS is " + modelTargetNamespace);
    if (modelTargetNamespace == null)
    {
      modelTargetNamespace = "";
    }
        
    String targetNamespace = newTargetNamespace.trim(); 
    String prefix = newPrefix.trim();

    if (!validatePrefix(prefix) || !validateTargetNamespace(targetNamespace))
    {
      return;
    }
        
    if (prefix.length() > 0 && targetNamespace.length() == 0)
    {
       // can't have blank targetnamespace and yet specify a prefix
       return;
    }

    doc.getModel().beginRecording(this, XSDEditorPlugin.getXSDString("_UI_LABEL_TARGETNAMESPACE_CHANGE"));
    String xsdForXSDPrefix = xsdSchema.getSchemaForSchemaQNamePrefix();
    Map map = xsdSchema.getQNamePrefixToNamespaceMap();

// For debugging
//        System.out.println("1. SW Map is " + map.values());
//        System.out.println("1. SW Map keys are " + map.keySet());

    // Check if prefix is blank
    // if it is, then make sure we have a prefix 
    // for schema for schema
    if (prefix.length() == 0)
    {
      // if prefix for schema for schema is blank
      // then set it to value specified in preference
      // and update ALL nodes with this prefix
      if (xsdForXSDPrefix == null || (xsdForXSDPrefix != null && xsdForXSDPrefix.trim().length() == 0))
      {
        // get preference prefix
        xsdForXSDPrefix = XSDEditorPlugin.getPlugin().getXMLSchemaPrefix();
        // get a unique prefix by checking what's in the map

        xsdForXSDPrefix = getUniqueSchemaForSchemaPrefix(xsdForXSDPrefix, map);
        element.setAttribute("xmlns:" + xsdForXSDPrefix, XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);

        updateAllNodes(element, xsdForXSDPrefix);
            
        // remove the old xmlns attribute for the schema for schema
        if (element.getAttribute("xmlns") != null &&
            element.getAttribute("xmlns").equals(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001))
        {
          element.removeAttribute("xmlns");
        }
      }
    }

    if (targetNamespace.length() > 0 ||
       (targetNamespace.length() == 0 && prefix.length() == 0))
    {
      // clean up the old prefix for this schema
      if (oldPrefix != null && oldPrefix.length() > 0)
      {
        element.removeAttribute("xmlns:"+oldPrefix);
//            element.setAttribute("xmlns:" + prefix, targetNamespace);
//            java.util.Map prefixToNameSpaceMap = xsdSchema.getQNamePrefixToNamespaceMap();
//            prefixToNameSpaceMap.remove(oldPrefix);
      }
      else // if no prefix
      {
        if (element.getAttribute("xmlns") != null)
        {
          if (!element.getAttribute("xmlns").equals(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001))
           {
            element.removeAttribute("xmlns");
          }
        }
      }
    }

    if (targetNamespace.length() > 0)
    {
      if (!modelTargetNamespace.equals(targetNamespace))
      {
        element.setAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE, targetNamespace);
      }
      // now set the new xmlns:prefix attribute
      if (prefix.length() > 0)
      {
        element.setAttribute("xmlns:" + prefix, targetNamespace);
      }
      else
      {
        element.setAttribute("xmlns", targetNamespace);
      }
      // set the targetNamespace attribute
    }
    else // else targetNamespace is blank
    {
      if (prefix.length() == 0)
      {
        element.removeAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE);
      }
    }

//    System.out.println("1.5 SW Map is " + map.values());
//    System.out.println("1.5 SW Map keys are " + map.keySet());
    
    // do our own referential integrity
    TargetNamespaceChangeHandler targetNamespaceChangeHandler = new TargetNamespaceChangeHandler(xsdSchema, oldNamespace, targetNamespace);
    targetNamespaceChangeHandler.resolve();

    oldPrefix = prefix;
    oldNamespace = targetNamespace;
    
    XSDSchemaHelper.updateElement(xsdSchema);
    
    doc.getModel().endRecording(this);

// For debugging
        map = xsdSchema.getQNamePrefixToNamespaceMap();
//        System.out.println("2. SW Map is " + map.values());
//        System.out.println("2. SW Map keys are " + map.keySet());
  }


  private String getUniqueSchemaForSchemaPrefix(String xsdForXSDPrefix, Map map)
  {
    if (xsdForXSDPrefix == null || (xsdForXSDPrefix != null && xsdForXSDPrefix.trim().length() == 0))
     {       
      xsdForXSDPrefix = "xsd";
    }
    // ensure prefix is unique
    int prefixExtension = 1;
    while (map.containsKey(xsdForXSDPrefix) && prefixExtension < 100)
     {
      xsdForXSDPrefix = xsdForXSDPrefix + String.valueOf(prefixExtension);
      prefixExtension++;
    }
    return xsdForXSDPrefix;
  }

  private void updateAllNodes(Element element, String prefix)
  {
    element.setPrefix(prefix);
    NodeList list = element.getChildNodes();
    if (list != null)
    {
      for (int i=0; i < list.getLength(); i++)
      {
        Node child = list.item(i);
        if (child != null && child instanceof Element)
        {
          child.setPrefix(prefix);
          if (child.hasChildNodes())
          {
            updateAllNodes((Element)child, prefix);
          }
        }
      }
    }   
  }

  protected boolean validateTargetNamespace(String ns)
  {
    // will allow blank namespace !!
    if (ns.equals(""))
     {
      return true;
    }
    
    String errorMessage = null;
    try
    {
      URI testURI = new URI(ns);
      testURI.isAbsolute();
    }
    catch (URISyntaxException e)
    {
      errorMessage = XSDEditorPlugin.getXSDString("_WARN_INVALID_TARGET_NAMESPACE");
    }
    
    if (errorMessage == null || errorMessage.length() == 0)
     {
      return true;
    }
    return false;
  }
  
}

