/*******************************************************************************
 * 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.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.Display;
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.ui.views.properties.PropertyDescriptor;
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.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 TypesPropertyDescriptor extends PropertyDescriptor
{
  Element element;
  XSDSchema xsdSchema;
  String property;
  /**
   * @param id
   * @param displayName
   */
  public TypesPropertyDescriptor(Object id, String displayName, Element element, XSDSchema xsdSchema)
  {
    super(id, displayName);
    this.property = (String)id;
    this.element = element;
    this.xsdSchema = xsdSchema;
  }
  
  boolean showComplexTypes = true;

  public CellEditor createPropertyEditor(Composite parent)
  {
    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;
    }
    // CellEditor editor = new TypesOptionsTextCellEditor(parent);
    CellEditor editor = new TypesDialogCellEditor(parent);
    if (getValidator() != null)
      editor.setValidator(getValidator());
    return editor;
  }

  
  public class TypesDialogCellEditor extends DialogCellEditor
  {

    /**
     * Creates a new Font dialog cell editor parented under the given control.
     * The cell editor value is <code>null</code> initially, and has no 
     * validator.
     *
     * @param parent the parent control
     */
    protected TypesDialogCellEditor(Composite parent)
    {
      super(parent);
    }

    protected Object openDialogBox(Control cellEditorWindow)
    {
	    Shell shell = Display.getCurrent().getActiveShell();
	    
	    TypesDialog dialog = new TypesDialog(shell);

	    dialog.setBlockOnOpen(true);
	    dialog.create();
	    
	    String value = (String)getValue();
	
	    int result = dialog.open();
	    
	    if (result == Window.OK)
	    {
	      value = dialog.getType();
        doSetValue(value);
        fireApplyEditorValue();
	    }
	    deactivate();
	    return null;
	  }
  }

  public class TypesDialog extends org.eclipse.jface.dialogs.Dialog implements SelectionListener
  {
    String type;
    Object typeObject;
    Table table;

    TypeSection typeSection;
    boolean showAnonymous = true;
    String previousStringType = "";
    boolean isAnonymous;
    int previousType;

    
    public TypesDialog(Shell shell)
    {
      super(shell);
    }

    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)
    {
      int tabIndex = 0;
      Composite client = (Composite)super.createDialogArea(parent);
      getShell().setText("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);
      }

      table = new Table(client,
                        SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL); 
      table.setHeaderVisible(false);
      table.setLinesVisible(true);
      
      GridData gd2 = new GridData();
      gd2.grabExcessHorizontalSpace = true;
      gd2.grabExcessVerticalSpace = true;
      gd2.horizontalAlignment = GridData.FILL;
      gd2.heightHint = 200;
      table.setLayoutData(gd2);

      TableColumn 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 widgetSelected(SelectionEvent e)
    {
      if (e.widget == typeSection.getSimpleType() && typeSection.getSimpleType().getSelection())
      {
        populateBuiltInType();
      }
      else if (e.widget == typeSection.getUserComplexType() && typeSection.getUserComplexType().getSelection())
      {
        populateUserComplexType();
      }
      else if (e.widget == typeSection.getUserSimpleType() && typeSection.getUserSimpleType().getSelection())
      {
        populateUserSimpleType();
      }

    }
    
  	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
      {
        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 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 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));
      }
    }

    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 + ":");
      updateElementToNotAnonymous(element);
      boolean hasChildrenElements = hasElementChildren(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.appendChild(childNode);
      //formatChild(childNode, hasChildrenElements);
    }

    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;
    }

    void updateElementToNotAnonymous(Element element)
    {
      if (element != null)
      {
	      NodeList children = element.getChildNodes();
	      if (children != null)
	       {
	        for (int i = 0; i < children.getLength(); i++)
	         {
	          Node node = (Node) children.item(i);
	          if (node instanceof Element)
	           {
	            if (node.getLocalName().equals(XSDConstants.SIMPLETYPE_ELEMENT_TAG)
	                || node.getLocalName().equals(XSDConstants.COMPLEXTYPE_ELEMENT_TAG))
	             {
	              XSDDOMHelper.removeNodeAndWhitespace(node);
	              i = 0;
	            }
	          }
	        }
	      }
      }
    }

    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;
	  }

  }

  
  
  
  
  
  
  
  class TypesOptionsTextCellEditor extends OptionsTextCellEditor
  {
    boolean showAnonymous = true;
    
    public TypesOptionsTextCellEditor(Composite parent)
    {
      super(parent);
    }

    protected Control createControl(Composite parent)
    {
      isTextReadOnly = true;
      return super.createControl(parent);
    }

    Table table;
    TypeSection typeSection;

    protected void openDialog()
    {
      typeObject = null;
      dialog = new Shell(XSDEditorPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.MODELESS);
      Display display = dialog.getDisplay();
      GridLayout gl = new GridLayout(1, true);
      gl.marginHeight = 0;
      gl.marginWidth = 0;
      gl.horizontalSpacing = 0;
      gl.verticalSpacing = 0;
      dialog.setLayout(gl);
      GridData gd = new GridData();
      gd.grabExcessHorizontalSpace = true;
      gd.grabExcessVerticalSpace = true;
      gd.horizontalAlignment = GridData.FILL;
      gd.verticalAlignment = GridData.FILL;
      gd.horizontalIndent = 0;
      dialog.setLayoutData(gd);

      
      
      typeSection = new TypeSection(dialog);
      typeSection.setShowUserComplexType(showComplexTypes);

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

      table = new Table(dialog,
                        SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL); 
      table.setHeaderVisible(false);
      table.setLinesVisible(true);
      GridData gd2 = new GridData();
      gd2.grabExcessHorizontalSpace = true;
      gd2.grabExcessVerticalSpace = true;
      gd2.horizontalAlignment = GridData.FILL;
      gd2.verticalAlignment = GridData.FILL;
      table.setLayoutData(gd2);

      // Fill table and select input type
      handleSetInput();
      int tableItemCount = table.getItemCount();

      TableColumn tc = new TableColumn(table, SWT.LEFT);
      tc.setImage(XSDEditorPlugin.getXSDImage("icons/XSDElement.gif"));
      //tc.setText("Available types:");
      tc.setResizable(false);

      int MAX_ITEMS = 23;
//      tc.pack();
//      table.pack();
      Rectangle tableBounds = table.getBounds();
      tableBounds.height = Math.min(tableBounds.height, table.getItemHeight()*MAX_ITEMS);
      table.setBounds(tableBounds);
      dialog.pack();
      
      dialog.addShellListener(new ShellAdapter()
      {
        public void shellDeactivated(ShellEvent e)
        {
          cancel();
        }
      });

      Rectangle dialogBounds = dialog.getBounds();
      Point buttonLocation = getButtonAbsoluteLocation();
      dialogBounds.x = buttonLocation.x;
      dialogBounds.y = buttonLocation.y;

      if (dialogBounds.height > 200)
      {        
        dialogBounds.height = 200;
      }
      if (dialogBounds.height < 100)
      {
        dialogBounds.height = 200;
      }
      if (dialogBounds.width > 200)
      {
        dialogBounds.width = typeSection.getUserComplexType().getBounds().width + 30;
      }
      dialog.setBounds(dialogBounds);
      tc.setWidth(dialogBounds.width);

      table.addKeyListener(new KeyAdapter()
      {
        public void keyPressed(KeyEvent e)
        {
          int keyCode = e.keyCode;
          int stateMask = e.stateMask;
          char character = e.character;
          if (character == SWT.CR || character == SWT.LF)
            ok();
          else if (character == SWT.ESC)
            cancel();
        }
      });

      table.addMouseListener(new MouseAdapter()
      {
        public void mouseDoubleClick(MouseEvent e)
        {
          ok();
        }
        public void mouseDown(MouseEvent e)
        {
          ok();
        }
      });

      try
      {
        dialog.open();
        table.setFocus();
        table.showSelection();
        
        while (!dialog.isDisposed())
        {
          if (!display.readAndDispatch())
          {
            display.sleep();
          }
        }
      }
      finally
      {
        if (!dialog.isDisposed())
          cancel();
      }
    }
    
    public void widgetSelected(SelectionEvent e)
    {
      if (e.widget == typeSection.getSimpleType() && typeSection.getSimpleType().getSelection())
      {
        populateBuiltInType();
      }
      else if (e.widget == typeSection.getUserComplexType() && typeSection.getUserComplexType().getSelection())
      {
        populateUserComplexType();
      }
      else if (e.widget == typeSection.getUserSimpleType() && typeSection.getUserSimpleType().getSelection())
      {
        populateUserSimpleType();
      }
    }
    
    protected void cancel()
    {
      super.cancel();
      table.dispose();
    }

    protected void ok()
    {
      TableItem[] items = table.getItems();
      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
      {
        updateElementToNotAnonymous(element);
        //element.setAttribute(XSDConstants.TYPE_ATTRIBUTE, typeObject.toString());
        element.setAttribute(property, typeObject.toString());
      }
      }
//      endRecording(element);

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

    String previousStringType = "";
    boolean isAnonymous;
    int previousType;

    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 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 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));
      }
    }

    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 + ":");
      updateElementToNotAnonymous(element);
      boolean hasChildrenElements = hasElementChildren(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.appendChild(childNode);
      //formatChild(childNode, hasChildrenElements);
    }

    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;
    }

    void updateElementToNotAnonymous(Element element)
    {
      NodeList children = element.getChildNodes();
      if (children != null)
       {
        for (int i = 0; i < children.getLength(); i++)
         {
          Node node = (Node) children.item(i);
          if (node instanceof Element)
           {
            if (node.getLocalName().equals(XSDConstants.SIMPLETYPE_ELEMENT_TAG)
                || node.getLocalName().equals(XSDConstants.COMPLEXTYPE_ELEMENT_TAG))
             {
              XSDDOMHelper.removeNodeAndWhitespace(node);
              i = 0;
            }
          }
        }
      }
    }

    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;
	  }

  }

}
