/*******************************************************************************
 * 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.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.xsd.ui.internal.XSDEditorPlugin;
import org.eclipse.wst.xsd.ui.internal.util.TypesHelper;
import org.eclipse.wst.xsd.ui.internal.util.ViewUtility;
import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
import org.eclipse.wst.xsd.ui.internal.widgets.TypeSection;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class TypesDialog extends Dialog implements SelectionListener, Listener
{
  XSDSchema xsdSchema;
  String property;

  /**
   * @param parentShell
   */
  public TypesDialog(Shell parentShell, Element element, Object id, XSDSchema xsdSchema)
  {
    super(parentShell);
    setShellStyle(getShellStyle() | SWT.RESIZE);
    this.element = element;
    this.property = (String)id;
    this.element = element;
    this.xsdSchema = xsdSchema;

    if (XSDDOMHelper.inputEquals(element, XSDConstants.ELEMENT_ELEMENT_TAG, false))
    {
      showComplexTypes = true;
    }
    else if (XSDDOMHelper.inputEquals(element, XSDConstants.ATTRIBUTE_ELEMENT_TAG, false) ||
      XSDDOMHelper.inputEquals(element, XSDConstants.LIST_ELEMENT_TAG, false) ||
      XSDDOMHelper.inputEquals(element, XSDConstants.UNION_ELEMENT_TAG, false))
    {
      showComplexTypes = false;
    }
  }

  String type;
  Object typeObject;
  Text textField;
  Table table;
  TableColumn tableColumn;
  Element element;
  
  boolean showComplexTypes = true;
  TypeSection typeSection;
  boolean showAnonymous = true;
  String previousStringType = "";
  boolean isAnonymous;
  int previousType;

  protected void configureShell(Shell shell)
  {
    super.configureShell(shell);
  }

  protected void buttonPressed(int buttonId)
  {
    if (buttonId == Dialog.OK)
    {
      type = table.getItem(table.getSelectionIndex()).getText();
      ok();
    }
    super.buttonPressed(buttonId);
  }

  public Object getTypeObject() { return typeObject; }
  public String getType() { return type; }

  //
  // Create the controls
  //
  public Control createDialogArea(Composite parent)
  {
    Composite client = (Composite)super.createDialogArea(parent);
    getShell().setText(XSDEditorPlugin.getXSDString("_UI_LABEL_AVAILABLE_TYPES"));

    typeObject = null;
    
    GridLayout gl = new GridLayout(1, true);
//    gl.marginHeight = 0;
//    gl.marginWidth = 0;
//    gl.horizontalSpacing = 0;
//    gl.verticalSpacing = 0;
    client.setLayout(gl);

    GridData gd = new GridData();
    gd.grabExcessHorizontalSpace = true;
    gd.grabExcessVerticalSpace = true;
    gd.horizontalAlignment = GridData.FILL;
    gd.verticalAlignment = GridData.FILL;
    gd.horizontalIndent = 0;
    client.setLayoutData(gd);
    
    typeSection = new TypeSection(client);
    typeSection.setShowUserComplexType(showComplexTypes);

    typeSection.createClient(client);
    typeSection.getSimpleType().setSelection(false);
    typeSection.getSimpleType().addSelectionListener(this);
    typeSection.getUserSimpleType().addSelectionListener(this);
    if (showComplexTypes)
    {
      typeSection.getUserComplexType().addSelectionListener(this);
    }

    textField = ViewUtility.createTextField(client, 50);
    textField.addListener(SWT.Modify, this);
    ViewUtility.createVerticalFiller(client, 0);

    table = new Table(client,
                      SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL); 
    table.setHeaderVisible(false);
    table.setLinesVisible(true);
    table.addSelectionListener(this);
    
    GridData gd2 = new GridData();
    gd2.grabExcessHorizontalSpace = true;
    gd2.grabExcessVerticalSpace = true;
    gd2.horizontalAlignment = GridData.FILL;
    gd2.verticalAlignment = GridData.FILL;
    gd2.heightHint = 200;
    table.setLayoutData(gd2);
    table.addListener(SWT.Resize, this);
    
    tableColumn = new TableColumn(table, SWT.LEFT);
//    tableColumn.setImage(XSDEditorPlugin.getXSDImage("icons/XSDElement.gif"));
    tableColumn.setResizable(true);
    tableColumn.setWidth(200);

    // Fill table and select input type
    handleSetInput();

    return client;
  }
  
  public void handleEvent(Event event)
  {
  	if (event.type == SWT.Resize && event.widget == table) {
  		tableColumn.setWidth(table.getSize().x);
  	}
  	else if (event.type == SWT.Modify && event.widget == textField) {
  		boolean showAll = false;
  		String inputString = textField.getText();
  		
  		if (inputString.equals("")) {
  			showAll = true;
  		}
  		else {
  			inputString = insertString("*", ".", inputString);
  			inputString = insertString("?", ".", inputString);
  			inputString = inputString + ".*";
  		}
  		
  		try {
  			if (typeSection.getSimpleType().getSelection())
  			{
  				if (showAll) {
  					populateBuiltInType();
  				}
  				else {
  					populateBuiltInType(inputString);
  				}
  			}
  			else if (typeSection.getUserComplexType().getSelection())
  			{
  				if (showAll) {
  					populateUserComplexType();
  				}
  				else {
  					populateUserComplexType(inputString);
  				}
  			}
  			else if (typeSection.getUserSimpleType().getSelection())
  			{
  				if (showAll) {
  					populateUserSimpleType();
  				}
  				else {
  					populateUserSimpleType(inputString);
  				}
  			}
  		}
  		catch (Exception e) {
  			// Do nothing
  		}
  	}
  	
  	setEnabledState();
  }
  
  private void setEnabledState() {
  	if (table.getSelectionIndex() != -1) {
  		this.getButton(IDialogConstants.OK_ID).setEnabled(true);
  	}
  	else {
  		this.getButton(IDialogConstants.OK_ID).setEnabled(false);
  	}
  }
  
  private String insertString(String target, String newString, String string) {
  	StringBuffer stringBuffer = new StringBuffer(string);
  	
  	int index = stringBuffer.indexOf(target);
  	while (index != -1) {
  		stringBuffer = stringBuffer.insert(index, newString);
  		index = stringBuffer.indexOf(target, index + newString.length() + target.length());
  	}
  	
  	return stringBuffer.toString();
  }
  
  public void widgetSelected(SelectionEvent e)
  {
    if (e.widget == typeSection.getSimpleType() && typeSection.getSimpleType().getSelection())
    {
    	if (textField.getText().equals("")) {
    		populateBuiltInType();
    	}
    	else {
    		populateBuiltInType(textField.getText());
    	}
    }
    else if (e.widget == typeSection.getUserComplexType() && typeSection.getUserComplexType().getSelection())
    {
    	if (textField.getText().equals("")) {
    		populateUserComplexType();
    	}
    	else {
    		populateUserComplexType(textField.getText());
    	}
    }
    else if (e.widget == typeSection.getUserSimpleType() && typeSection.getUserSimpleType().getSelection())
    {
    	if (textField.getText().equals("")) {
    		populateUserSimpleType();
    	}
    	else {
    		populateUserSimpleType(textField.getText());
    	}
    }
    setEnabledState();
  }
  
	public void widgetDefaultSelected(SelectionEvent e)
  {
  }

  protected void ok()
  {
    TableItem[] items = table.getItems();
    int selection = table.getSelectionIndex();
    if (items != null && items.length > 0 && selection >= 0)
    {
      typeObject = items[selection].getData();
    }
//    System.out.println("typeObject is " + typeObject);

//    beginRecording(XSDEditorPlugin.getXSDString("_UI_ELEMENT_TYPE_CHANGE"), element);
//    beginRecording(XSDEditorPlugin.getXSDString("_UI_TYPE_CHANGE"), element);
//    doSetValue(typeObject);
//    applyEditorValueAndDeactivate();
//    dialog.close();

    if (!XSDDOMHelper.inputEquals(element, XSDConstants.UNION_ELEMENT_TAG, false))
    {
	    if (typeObject.equals("**anonymous**"))
	    {
	      if (typeSection.getUserSimpleType().getSelection())
	      {
//	        if (!previousStringType.equals("**anonymous**"))
	        {
	          updateElementToAnonymous(element, XSDConstants.SIMPLETYPE_ELEMENT_TAG);
	        }
	      }
	      else
	      {
//	        if (!previousStringType.equals("**anonymous**"))
	        {
	          updateElementToAnonymous(element, XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
	        }
	      }
	      // element.removeAttribute(XSDConstants.TYPE_ATTRIBUTE);
	      element.removeAttribute(property);
	    }
	    else
	    {
	      XSDDOMHelper.updateElementToNotAnonymous(element);
	      //element.setAttribute(XSDConstants.TYPE_ATTRIBUTE, typeObject.toString());
	      element.setAttribute(property, typeObject.toString());
	    }
    }
//    endRecording(element);

    //implement dispose();
//    table.removeAll();
//    table.dispose();
  }

	
  public void handleSetInput()
  {
    table.removeAll();
    isAnonymous = checkForAnonymousType(element);
    // Attr attr = element.getAttributeNode(XSDConstants.TYPE_ATTRIBUTE);
    Attr attr = element.getAttributeNode(property);
    if (attr != null)
    {
      String value = attr.getValue();
      if (typeSection.getBuiltInTypeNamesList(xsdSchema).contains(value))
      {
        typeSection.getSimpleType().setSelection(true);
        populateBuiltInType();
        int i = typeSection.getBuiltInTypeNamesList(xsdSchema).indexOf(value);
        table.setSelection(i);
        previousType = 1;
      }
      else if (typeSection.getUserSimpleTypeNamesList(xsdSchema).contains(value))
      {
        typeSection.getUserSimpleType().setSelection(true);
        populateUserSimpleType();
        int i = typeSection.getUserSimpleTypeNamesList(xsdSchema).indexOf(value);
        if (showAnonymous)
        {
          table.setSelection(i + 1);
        }
        else
        {
          table.setSelection(i);
        }
        previousType = 2;
      }
      else if (typeSection.getUserComplexTypeNamesList(xsdSchema).contains(value))
      {
        typeSection.getUserComplexType().setSelection(true);
        populateUserComplexType();
        int i = typeSection.getUserComplexTypeNamesList(xsdSchema).indexOf(value);
        if (showAnonymous)
         {
          table.setSelection(i + 1);
        }
        else
         {
          table.setSelection(i);
        }
        previousType = 3;
      }
      else // if it is type="" for an empty list of simple types
        {
        typeSection.getUserSimpleType().setSelection(true);
        populateUserSimpleType();
        previousType = 2;
      }
    }
    else
    {
      if (isAnonymous)
      {
        if (isSTAnonymous(element))
        {
          typeSection.getUserSimpleType().setSelection(true);
          populateUserSimpleType();
          previousType = 2;
        }
        else
        {
          typeSection.getUserComplexType().setSelection(true);
          populateUserComplexType();
          previousType = 3;
        }
        table.setSelection(0); // anonymous
        //        typeSection.getTypeList().setText("**anonymous**");
      }
      else
      {
        typeSection.getSimpleType().setSelection(true);
        populateBuiltInType();
        table.setSelection(0);
        
        //        typeSection.getTypeList().setEnabled(true);
        //        typeSection.getSimpleType().setSelection(true);
        //        typeSection.populateBuiltInType(xsdSchema);
        //        typeSection.getTypeList().setText(XSDEditorPlugin.getXSDString("_UI_NO_TYPE"));
        previousType = 1;
      }
    }
    if (table.getSelection() != null && table.getSelection().length > 0)
    {
      previousStringType = (table.getSelection()[0]).getText();
    }
  }
  
  public void populateBuiltInType()
  {
    table.removeAll();
    List items = getBuiltInTypeNamesList();
    for (int i = 0; i < items.size(); i++)
    {
      TableItem item = new TableItem(table, SWT.NONE);
      item.setText(items.get(i).toString());
      item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif"));
      item.setData(items.get(i));
    }
  }

  public void populateBuiltInType(String fragment)
  {
    table.removeAll();
    List items = getBuiltInTypeNamesList();
    fragment = fragment.toLowerCase();
	Pattern regex = Pattern.compile(fragment);
	
    for (int i = 0; i < items.size(); i++)
    {
    	String itemString = items.get(i).toString().toLowerCase();
    	Matcher m = regex.matcher(itemString);

    	if (itemString.startsWith(fragment) || m.matches()) {
    		TableItem item = new TableItem(table, SWT.NONE);
    		item.setText(items.get(i).toString());
    		item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif"));
    		item.setData(items.get(i));
    	}
    }
    
    table.select(0);
  }

  public void populateUserComplexType()
  {
    table.removeAll();
    if (showAnonymous)
    {
      TableItem anonymousItem = new TableItem(table, SWT.NONE);
      anonymousItem.setText("**anonymous**");
      anonymousItem.setData("**anonymous**");
    }
    List items = getUserComplexTypeNamesList();
    for (int i = 0; i < items.size(); i++)
    {
      TableItem item = new TableItem(table, SWT.NONE);
//      System.out.println("item " + i + " is " + item);
      item.setText(items.get(i).toString());
      item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDComplexType.gif"));
      item.setData(items.get(i));
    }
  }
  
  public void populateUserComplexType(String fragment)
  {
    table.removeAll();
    fragment = fragment.toLowerCase();
    Pattern regex = java.util.regex.Pattern.compile(fragment);
    
    if (showAnonymous)
    {
    	Matcher m = regex.matcher("**anonymous**");
    	if ("**anonymous**".startsWith(fragment) || m.matches()) {
    		TableItem anonymousItem = new TableItem(table, SWT.NONE);
    		anonymousItem.setText("**anonymous**");
    		anonymousItem.setData("**anonymous**");
    	}
    }
    List items = getUserComplexTypeNamesList();
    for (int i = 0; i < items.size(); i++)
    {
    	String itemString = items.get(i).toString().toLowerCase();
    	Matcher m = regex.matcher(itemString);
    	
    	if (itemString.startsWith(fragment) || m.matches()) {
    		TableItem item = new TableItem(table, SWT.NONE);
    		item.setText(items.get(i).toString());
    		item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDComplexType.gif"));
    		item.setData(items.get(i));
    	}
    }
    
    table.select(0);
  }

  public void populateUserSimpleType()
  {
    table.removeAll();
    if (showAnonymous)
     {
      TableItem anonymousItem = new TableItem(table, SWT.NONE);
      anonymousItem.setText("**anonymous**");
      anonymousItem.setData("**anonymous**");
    }
    List items = getUserSimpleTypeNamesList();
    for (int i = 0; i < items.size(); i++)
     {
      TableItem item = new TableItem(table, SWT.NONE);
      item.setText(items.get(i).toString());
      item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif"));
      item.setData(items.get(i));
    }
  }

  public void populateUserSimpleType(String fragment)
  {
    table.removeAll();
    fragment = fragment.toLowerCase();
    Pattern regex = java.util.regex.Pattern.compile(fragment);
    
    if (showAnonymous)
     {
    	Matcher m = regex.matcher("**anonymous**");
    	if ("**anonymous**".startsWith(fragment) || m.matches())  {
    		TableItem anonymousItem = new TableItem(table, SWT.NONE);
    		anonymousItem.setText("**anonymous**");
    		anonymousItem.setData("**anonymous**");
    	}
    }
    List items = getUserSimpleTypeNamesList();
    for (int i = 0; i < items.size(); i++)
     {
    	String itemString = items.get(i).toString().toLowerCase();
    	Matcher m = regex.matcher(itemString);
    	
    	if (itemString.startsWith(fragment) || m.matches()) {
    		TableItem item = new TableItem(table, SWT.NONE);
    		item.setText(items.get(i).toString());
    		item.setImage(XSDEditorPlugin.getXSDImage("icons/XSDSimpleType.gif"));
    		item.setData(items.get(i));
    	}
    }
    
    table.select(0);
  }
  
  boolean checkForAnonymousType(Element element)
  {
    /*
     * Using Ed's model to check boolean isAnonymous = false;
     * 
     * XSDConcreteComponent component =
     * getXSDSchema().getCorrespondingComponent(element); if (component
     * instanceof XSDElementDeclaration) { XSDElementDeclaration xsdElem =
     * (XSDElementDeclaration)component; isAnonymous =
     * xsdElem.isSetAnonymousTypeDefinition(); } return isAnonymous;
     */
    XSDDOMHelper helper = new XSDDOMHelper();
    boolean isAnonymous = false;
    Node aNode =
    helper.getChildNode(element, XSDConstants.SIMPLETYPE_ELEMENT_TAG);
    if (aNode != null)
     {
      return true;
    }
    aNode = helper.getChildNode(element, XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
    if (aNode != null)
     {
      isAnonymous = true;
    }
    return isAnonymous;
  }

  void updateElementToAnonymous(Element element, String xsdType)
  {
    String prefix = element.getPrefix();
    prefix = (prefix == null) ? "" : (prefix + ":");
    XSDDOMHelper.updateElementToNotAnonymous(element);
    Element childNode = null;
    if (xsdType.equals(XSDConstants.COMPLEXTYPE_ELEMENT_TAG))
    {
      childNode = element.getOwnerDocument().createElementNS(
          XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001,
          prefix + XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
    }
    else if (xsdType.equals(XSDConstants.SIMPLETYPE_ELEMENT_TAG))
    {
      childNode = element.getOwnerDocument().createElementNS(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001, prefix + XSDConstants.SIMPLETYPE_ELEMENT_TAG);
      
      Element restrictionNode = element.getOwnerDocument().createElementNS(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001, prefix + XSDConstants.RESTRICTION_ELEMENT_TAG);
      restrictionNode.setAttribute(XSDConstants.BASE_ATTRIBUTE, prefix + "string");
      childNode.appendChild(restrictionNode);      
    }
    if (childNode != null)
    {
      XSDDOMHelper helper = new XSDDOMHelper();
      Node annotationNode = helper.getChildNode(element, XSDConstants.ANNOTATION_ELEMENT_TAG);
      if (annotationNode == null)
      {
        Node firstChild = element.getFirstChild();
        element.insertBefore(childNode, firstChild);
      }
      else
      {
        Node nextSibling = annotationNode.getNextSibling();
        element.insertBefore(childNode, nextSibling);
      }
      XSDDOMHelper.formatChild(childNode);
    }
  }

  boolean isSTAnonymous(Element element)
  {
    XSDDOMHelper helper = new XSDDOMHelper();
    Node aNode = helper.getChildNode(element, XSDConstants.SIMPLETYPE_ELEMENT_TAG);
    if (aNode != null)
    {
      if (XSDDOMHelper.inputEquals(aNode, XSDConstants.SIMPLETYPE_ELEMENT_TAG, false))
      {
        return true;
      }
    }
    return false;
  }

  boolean isCTAnonymous(Element element)
  {
    XSDDOMHelper helper = new XSDDOMHelper();
    Node aNode = helper.getChildNode(element, XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
    if (aNode != null)
     {
      if (XSDDOMHelper.inputEquals(aNode, XSDConstants.COMPLEXTYPE_ELEMENT_TAG, false))
       {
        return true;
      }
    }
    return false;
  }

  XSDTypeDefinition getAnonymousTypeDefinition(Element element)
  {
    XSDDOMHelper helper = new XSDDOMHelper();
    Node typeDefinitionNode =
    helper.getChildNode(element, XSDConstants.SIMPLETYPE_ELEMENT_TAG);
    if (typeDefinitionNode == null)
     {
      typeDefinitionNode = helper.getChildNode(element, XSDConstants.COMPLEXTYPE_ELEMENT_TAG);
    }
    if (typeDefinitionNode != null)
     {
      XSDConcreteComponent component =
      xsdSchema.getCorrespondingComponent(typeDefinitionNode);
      if (component instanceof XSDTypeDefinition)
       {
        return (XSDTypeDefinition) component;
      }
    }
    return null;
  }
  
  public java.util.List getBuiltInTypeNamesList()
  {
    TypesHelper helper = new TypesHelper(xsdSchema);
    return helper.getBuiltInTypeNamesList();
  }

  public java.util.List getUserSimpleTypeNamesList()
  {
    TypesHelper helper = new TypesHelper(xsdSchema);
    return helper.getUserSimpleTypeNamesList();
  }
  
  public java.util.List getUserComplexTypeNamesList()
  {
    TypesHelper helper = new TypesHelper(xsdSchema);
    return helper.getUserComplexTypeNamesList();
  }
  
  protected boolean hasElementChildren(Node parentNode)
  {
    boolean hasChildrenElements = false;
    if (parentNode != null && parentNode.hasChildNodes())
    {
      NodeList nodes = parentNode.getChildNodes();
      for (int i = 0; i < nodes.getLength(); i++)
      {
        if (nodes.item(i) instanceof Element)
        {
          hasChildrenElements = true;
          break;
        }
      }
    }
    return hasChildrenElements;
  }

}
