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

import java.util.ArrayList;
import java.util.EventObject;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.editors.text.JavaFileEditorInput;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager;
import org.eclipse.wst.sse.ui.internal.StructuredTextEditor;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xsd.ui.internal.graph.XSDGraphViewer;
import org.eclipse.wst.xsd.ui.internal.util.OpenOnSelectionHelper;
import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;

// public class XSDEditor extends StructuredTextMultiPageEditorPart
public class XSDEditor extends XSDMultiPageEditorPart implements ITabbedPropertySheetPageContributor
{
  protected XSDTextEditor textEditor;
  IFile resourceFile;
  XSDSelectionManager xsdSelectionManager;

  private IStructuredModel result;

  public XSDEditor()
  {
    super();
    xsdSelectionManager = new XSDSelectionManager();
  }

  InternalPartListener partListener = new InternalPartListener(this);
  
  // show outline view - defect 266116
  public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException
  {
    super.init(site, editorInput);
    
    IWorkbenchWindow dw=PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    IWorkbenchPage page=dw.getActivePage();
    getSite().getPage().addPartListener(partListener);
    try
    {
      if (page != null)
      {
//      page.showView("org.eclipse.ui.views.ContentOutline");
        page.showView("org.eclipse.ui.views.PropertySheet");
      }
    } catch (PartInitException e) 
    {
//       e.printStackTrace();
    }      
   }
  
  // For team support
  //  protected PropertyDirtyChangeListener propertyChangeListener;

  /**
   * Creates the pages of this multi-page editor.
   * <p>
   * Subclasses of <code>MultiPageEditor</code> must implement this method.
   * </p>
   */
  protected void createPages()
  {
    try
    {
      if (!loadFile())
        return;

      // source page MUST be created before design page, now
      createSourcePage();

      addSourcePage();
      buildXSDModel();

      // comment this line out to hide the graph page 
      // 
      createAndAddGraphPage();

      int pageIndexToShow = getDefaultPageTypeIndex();
      setActivePage(pageIndexToShow);
      
      addCommandStackListener();
      
      XSDEditorPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(preferenceStoreListener);
    }
    catch (PartInitException exception)
    {
      throw new SourceEditingRuntimeException(XSDEditorPlugin.getXSDString("An_error_has_occurred_when1_ERROR_")); //$NON-NLS-1$ = "An error has occurred when initializing the input for the the editor's source page."
    }
  }

  public String[] getPropertyCategories()
  {
    return new String[] { "general", "namespace", "other", "attributes", "documentation", "facets" }; //$NON-NLS-1$
  }

	/**
	 * @see org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor#getContributorId()
	 */ 
  public String getContributorId()
	{
    return "org.eclipse.wst.xsd.ui.internal.XSDEditor";
    //return getSite().getId();
  }

  protected CommandStackListener commandStackListener;
  protected void addCommandStackListener()
  {
    if (commandStackListener == null)
    {
      IStructuredTextUndoManager undoManager = getModel().getUndoManager();
        commandStackListener = new CommandStackListener()
        {
          /**
           * @see org.eclipse.emf.common.command.CommandStackListener#commandStackChanged(EventObject)
           */
          public void commandStackChanged(EventObject event)
          {
            Object obj = event.getSource();
            if (obj instanceof BasicCommandStack)
            {
              BasicCommandStack stack = (BasicCommandStack) obj;
              Command recentCommand = stack.getMostRecentCommand();
              Command redoCommand = stack.getRedoCommand();
              Command undoCommand = stack.getUndoCommand();
              if (recentCommand == redoCommand)
              {
                // there must have been an undo reset info tasks 
                resetInformationTasks();
              }
            }
          }
        };

//TODO WTP Port        undoManager.getCommandStack().addCommandStackListener(commandStackListener);
      
    }
  } 

  protected void pageChange(int arg)
  {
    super.pageChange(arg);
  }

  protected void removeCommandStackListener()
  {
    if (commandStackListener != null)
    {
      IStructuredTextUndoManager undoManager = getModel().getUndoManager();
//TODO WTP Port      undoManager.getCommandStack().removeCommandStackListener(commandStackListener);
    }
  }

  // This is from the IValidateEditEditor interface
/*  public void undoChange()
  {
    StructuredTextUndoManager undoManager = textEditor.getModel().getUndoManager();   
    undoManager.undo();
    // Make the editor clean
    textEditor.getModel().setDirtyState(false);
  } */

  private class PreferenceStoreListener implements IPropertyChangeListener
  {
    /**
     * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
     */
    public void propertyChange(PropertyChangeEvent event)
    {
    }
  }

  protected IPropertyChangeListener preferenceStoreListener = new PreferenceStoreListener();

  protected int getDefaultPageTypeIndex()
  {
    int pageIndex = sourcePageIndex;
    
    if (XSDEditorPlugin.getPlugin().getDefaultPage().equals(XSDEditorPlugin.GRAPH_PAGE))
    {
      if (graphPageIndex != -1)
        pageIndex = graphPageIndex;
    }
    
    return pageIndex;
  }
      
	int currentPage = -1;      
	public String getCurrentPageType()
	{
		// should update pref. for valid pages
		if (getActivePage() != -1)
		{
			currentPage = getActivePage();
		}
		if (currentPage == graphPageIndex)
		{
			return XSDEditorPlugin.GRAPH_PAGE;
		}
		else
		{
			return XSDEditorPlugin.SOURCE_PAGE;
    }
	}
	
	public Object getActivePart()
  {
		return getSite().getWorkbenchWindow().getActivePage().getActivePart();	
	}

  public void dispose()
  {
//    propertyChangeListener.dispose();
    removeCommandStackListener();
    
    XSDEditorPlugin.getPlugin().setDefaultPage(getCurrentPageType());
    XSDEditorPlugin.getPlugin().getPreferenceStore().removePropertyChangeListener(preferenceStoreListener);
    
    getSite().getPage().removePartListener(partListener);

    super.dispose();
  }

  protected boolean loadFile()
  {
    Object input = getEditorInput();

    if (input instanceof IFileEditorInput)
    {
      resourceFile = ((IFileEditorInput) input).getFile();
    }
    else if (input instanceof JavaFileEditorInput)
    {
      IPath path = ((JavaFileEditorInput)input).getPath(input);
      String ext = path.getFileExtension();
      if (ext != null && ext.equals("xsd"))
      {
        return true;
      }
      return false;
    }
    else
    {
//      XSDEditorPlugin.getPlugin().getMsgLogger().write("###Error...XSDEditor::createPages() .. Can't find input..Exiting..");
      return false;
    }
    return true;
  }

  /**
   * Method openOnGlobalReference.
   * The comp argument is a resolved xsd schema object from another file.  This is created and called from another
   * schema model to allow F3 navigation to open a new editor and choose the referenced object within that editor context
   * @param comp
   */
  public void openOnGlobalReference(XSDConcreteComponent comp)
  {
    openOnSelectionHelper.openOnGlobalReference(comp);
  }
  
  protected OpenOnSelectionHelper openOnSelectionHelper;

  public OpenOnSelectionHelper getOpenOnSelectionHelper()
  {
    return openOnSelectionHelper;
  }
  
  /**
   * @see org.eclipse.wst.xsd.ui.internal.XSDMultiPageEditorPart#createTextEditor()
   */
  protected StructuredTextEditor createTextEditor()
  {
    return new XSDTextEditor(this);
  }

  /*
   * @see StructuredTextMultiPageEditorPart#createSourcePage()
   */
  protected void createSourcePage() throws PartInitException
  {
    super.createSourcePage();
    
    textEditor = (XSDTextEditor) getTextEditor();

		openOnSelectionHelper = new OpenOnSelectionHelper(textEditor);
  }
 
  int sourcePageIndex = -1;
  /**
   * Adds the source page of the multi-page editor.
   */
  protected void addSourcePage() throws PartInitException {
  
    sourcePageIndex = addPage(textEditor, getEditorInput());
    setPageText(sourcePageIndex, XSDEditorPlugin.getXSDString("_UI_TAB_SOURCE"));

    // defect 223043 ... do textEditor.setModel() here instead of in createSourcePage()
		// the update's critical, to get viewer selection manager and highlighting to work
    IEditorInput editorInput = getEditorInput();
    if (editorInput instanceof IFileEditorInput)
    {
      textEditor.setModel((IFileEditorInput)getEditorInput());
    }
    else
    {
//      textEditor.setModel(editorInput);
    }
    textEditor.update();
		firePropertyChange(PROP_TITLE);
  }                       

  int graphPageIndex = -1;            
  XSDGraphViewer graphViewer;

  /**
   * Creates the graph page and adds it to the multi-page editor.
   */
  protected void createAndAddGraphPage() throws PartInitException 
  {                         
    graphViewer = new XSDGraphViewer(this);                              
    graphViewer.setSchema(xsdSchema);
    Control graphControl = graphViewer.createControl(getContainer());
    graphPageIndex = addPage(graphControl);
    setPageText(graphPageIndex, XSDEditorPlugin.getXSDString("_UI_TAB_GRAPH"));

    // graphViewer.setViewerSelectionManager(textEditor.getViewerSelectionManager());    
    graphViewer.setSelectionManager(getSelectionManager());
    
    // this forces the editor to initially select the top level schema object
    //
    getSelectionManager().setSelection(new StructuredSelection(textEditor.getXSDSchema()));    
  }

  /*
   * @see IAdaptable#getAdapter(Class)
   */
  public Object getAdapter(Class key)
  {
    Object result = null;
    if (key == ISelectionProvider.class)
    {
      result = xsdSelectionManager;
    }
    else 
    {
      result = textEditor.getAdapter(key);
    }
    return result;
  }

  public XSDSelectionManager getSelectionManager()
  {
    return xsdSelectionManager;
  }
 
  /**
   * @see org.eclipse.wst.xsd.ui.internal.XSDMultiPageEditorPart#doSaveAs()
   */
  public void doSaveAs()
  {
    super.doSaveAs();
  }

  public void doSave(org.eclipse.core.runtime.IProgressMonitor monitor)
  {
    super.doSave(monitor);
  }

  protected XSDSchema xsdSchema;
  protected ResourceSet resourceSet;

  public void reparseSchema()
  {
    Document document  = ((IDOMModel)getModel()).getDocument();
    createSchema(document.getDocumentElement());
  }
  
  public XSDSchema createSchema(Node node)
  {
    try
    {
      EPackage.Registry reg = EPackage.Registry.INSTANCE; 
      XSDPackage xsdPackage = (XSDPackage)reg.getEPackage(XSDPackage.eNS_URI);
      xsdSchema = xsdPackage.getXSDFactory().createXSDSchema();
      
      // Force the loading of the "meta" schema for schema instance instance.
      //
      String schemaForSchemaNamespace = node.getNamespaceURI();
      XSDSchemaImpl.getSchemaForSchema(schemaForSchemaNamespace);

      resourceSet = XSDSchemaImpl.createResourceSet();
      resourceSet.setURIConverter(new XSDURIConverter(resourceFile));

      String pathName = "";
      // If the resource is in the workspace....
      // otherwise the user is trying to open an external file
      if (resourceFile != null)
      {
        pathName = resourceFile.getFullPath().toString();
        Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(pathName), true);
//      resource.getContents().add(xsdSchema);
        resourceSet.getResources().add(resource);
      
        Object obj = resource.getContents().get(0);
        if (obj instanceof XSDSchema)
        {
          xsdSchema = (XSDSchema)obj;
        }

//      URIConverter uriConverter = resourceSet.getURIConverter();
//      resourceSet.setURIConverter(new XSDURIConverter(resourceFile));
 
        xsdSchema.setElement((Element)node);
        resource.setModified(false);
      }
      else
      {
        xsdSchema.setElement((Element)node);
      }
    }
    catch (StackOverflowError e)
    {
//      XSDEditorPlugin.getPlugin().getMsgLogger().write("Stack overflow encountered.  Possibly an invalid recursive circular schema");
    }
    catch (Exception ex)
    {
//      ex.printStackTrace();
    }
    
    return xsdSchema;
  }

  class XSDDocumentAdapter extends DocumentAdapter
  {
  	INodeNotifier currentNotifier;
  	int currentEventType;
  	
		public XSDDocumentAdapter(Document document)
		{
			super(document);
		}

		boolean handlingNotifyChanged = false;

		public void notifyChanged(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index)
		{
			if (!handlingNotifyChanged)
			{
				handlingNotifyChanged = true;
				try
				{
					// delay handle events only in the source view
					if (getCurrentPageType() == XSDEditorPlugin.SOURCE_PAGE &&
							!(getActivePart() instanceof PropertySheet) && 
							!(getActivePart() instanceof org.eclipse.ui.views.contentoutline.ContentOutline)) {
						startDelayedEvent(notifier, eventType, feature, oldValue, newValue, index);
					}
					else // all other views, just handle the events right away
					{
						handleNotifyChange(notifier, eventType, feature, oldValue, newValue, index);
					}
				}
				catch (Exception e)
				{
//					XSDEditorPlugin.getPlugin().getMsgLogger().write(e);
				}
				handlingNotifyChanged = false;
			}
		}

		public void handleNotifyChange(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index)
		{
//			System.out.println(eventType + " : HandleNotifyChange " + notifier.hashCode() + " notifier " + notifier);
			switch (eventType)
			{
				case INodeNotifier.ADD:
				{
					if (newValue instanceof Element)
					{
						adapt((Element)newValue);
//	Add			updateParentForDerivation(node, listener);
					}
					break;
				}
        case INodeNotifier.REMOVE:
        {
          Node node = (Node)notifier;
          XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node);
         
          if (listener instanceof XSDSchema)
          {
            // we want to reset the schema's external elements when the directive is deleted
            if (feature instanceof Element)
            {
              Element elem = (Element)feature;
              if (XSDDOMHelper.inputEquals(elem, XSDConstants.INCLUDE_ELEMENT_TAG, false) ||
                  XSDDOMHelper.inputEquals(elem, XSDConstants.IMPORT_ELEMENT_TAG, false) ||
                  XSDDOMHelper.inputEquals(elem, XSDConstants.REDEFINE_ELEMENT_TAG, false))
              {
                xsdSchema.reset();
                xsdSchema.update();
              }
            }
          }          
        }
				case INodeNotifier.CHANGE:
				{
					Node node = (Node)notifier;
			    XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node);
          if (node.getNodeType() == Node.ELEMENT_NODE)
          {
  		      listener.elementAttributesChanged((Element)node);
    	      listener.elementChanged((Element)node);
          }
          else if (node.getNodeType() == Node.DOCUMENT_NODE)
          {
            listener.elementAttributesChanged(((Document)node).getDocumentElement());
            listener.elementChanged(((Document)node).getDocumentElement());
          }
    	    break;
				}
				case INodeNotifier.STRUCTURE_CHANGED:
				case INodeNotifier.CONTENT_CHANGED:
				{
					Node node = (Node)notifier;
					XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node);
          if (node.getNodeType() == Node.ELEMENT_NODE)
					{
						listener.elementContentsChanged((Element)node);
						break;
					}
					else if (node.getNodeType() == Node.DOCUMENT_NODE)
					{
						Element docElement = ((Document)node).getDocumentElement();
						// Need to add check if doc element is being edited in the source
						if (docElement != null)
					  {
						  String prefix = docElement.getPrefix();
						  String xmlnsString = prefix == null? "xmlns" : "xmlns:" + prefix;
						  Attr attr = docElement.getAttributeNode(xmlnsString);
						  boolean doParse = false;
						  if (attr != null)
						  {
						    if (attr.getValue().equals(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001) && docElement.getLocalName().equals("schema"))
						    {
						      // We have a viable schema so parse it
						      doParse = true;
						    }
						  }
						  
							if (doParse)
							{
					      adapt(docElement);
 						    xsdSchema.setElement(docElement);
							}
					  }
					}
					break;
				}
			}
		}

		protected DelayedEvent delayedTask;
		protected void startDelayedEvent(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index)
		{
//			System.out.println("start delayed event");
      // check if there is already a delayed task for the same notifier and eventType
//			if (delayedTask != null)
//			{
//  			Notifier aNotifier = delayedTask.getNotifier();
//	  		int anEventType = delayedTask.getEventType();
//  			if (notifier == aNotifier && anEventType == eventType)
//			  {
//				  // same event, just different data, delay new event
//				  delayedTask.setCancel(true);
//			  }
//			}

			delayedTask = new DelayedEvent();

			delayedTask.setNotifier(notifier);
			delayedTask.setEventType(eventType);
			delayedTask.setFeature(feature);
			delayedTask.setOldValue(oldValue);
			delayedTask.setNewValue(newValue);
			delayedTask.setIndex(index);

			Display.getDefault().timerExec(400,delayedTask);
		}

		class DelayedEvent implements Runnable
		{
		  INodeNotifier notifier;
			int eventType;
			Object feature;
			Object oldValue;
			Object newValue;
			int index;
			boolean cancelEvent = false;

			/*
			 * @see Runnable#run()
			 */
			public void run()
			{
				if (!cancelEvent)
				{
				  handleNotifyChange(notifier, eventType, feature, oldValue, newValue, index);
				  if (delayedTask == this)
				  {
				  	delayedTask = null;
				  }
				}
			}
			
			public void setCancel(boolean flag)
			{
				cancelEvent = flag;
			}

			public void setNotifier(INodeNotifier notifier)
			{
				this.notifier = notifier;
			}
		
			public void setEventType(int eventType)
			{
				this.eventType = eventType;
			}

			public void setFeature(Object feature)
			{
				this.feature = feature;
			}

			public void setOldValue(Object oldValue)
			{
				this.oldValue = oldValue;			
			}

			public void setNewValue(Object newValue)
			{
				this.newValue = newValue;
			}

			public void setIndex(int index)
			{
				this.index = index;			
			}

			public INodeNotifier getNotifier()
			{
				return notifier;
			}

			public int getEventType()
			{
				return eventType;
			}

			public Object getNewValue()
			{
				return newValue;
			}

			public Object getOldValue()
			{
				return oldValue;
			}

		}
  }

  abstract class DocumentAdapter implements INodeAdapter
  {
    public DocumentAdapter(Document document)
    {
      ((INodeNotifier)document).addAdapter(this);
      adapt(document.getDocumentElement());
    }

    public void adapt(Element element)
    {
      if (((INodeNotifier)element).getExistingAdapter(this) == null)
      {

        ((INodeNotifier)element).addAdapter(this);

        for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling())
        {
          if (child.getNodeType() == Node.ELEMENT_NODE)
          {
            adapt((Element)child);
          }
        }
      }
    }

    public boolean isAdapterForType(Object type)
    {
      return type == this;
    }

    abstract public void notifyChanged
      (INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index);
  }


  /**
   * Method createDefaultSchemaNode.  Should only be called to insert a schema node into an empty document
   */
  public void createDefaultSchemaNode()
  {
    Document document  = ((IDOMModel)getModel()).getDocument();
    if (document.getChildNodes().getLength() == 0)
    {
      // if it is a completely empty file, then add the encoding and version processing instruction
//TODO  String encoding = EncodingHelper.getDefaultEncodingTag();
      String encoding = "UTF-8";
      ProcessingInstruction instr = document.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"" + encoding + "\"");
      document.appendChild(instr);
    }

    // Create a default schema tag now

    // String defaultPrefixForTargetNamespace = getFileResource().getProjectRelativePath().removeFileExtension().lastSegment();
    String defaultPrefixForTargetNamespace = "tns";
    String prefixForSchemaNamespace = "";
    String schemaNamespaceAttribute = "xmlns";
    if (XSDEditorPlugin.getPlugin().isQualifyXMLSchemaLanguage())
    {
      // Added this if check before disallowing blank prefixes in the preferences...
      // Can take this out.  See also NewXSDWizard
      if (XSDEditorPlugin.getPlugin().getXMLSchemaPrefix().trim().length() > 0)
      {
        prefixForSchemaNamespace = XSDEditorPlugin.getPlugin().getXMLSchemaPrefix() + ":";
        schemaNamespaceAttribute += ":" + XSDEditorPlugin.getPlugin().getXMLSchemaPrefix();
      }
    }
    
    document.appendChild(document.createTextNode("\n"));
    Element element = document.createElement(prefixForSchemaNamespace + XSDConstants.SCHEMA_ELEMENT_TAG);
    
    element.setAttribute(schemaNamespaceAttribute,"http://www.w3.org/2001/XMLSchema");
    
    String defaultTargetURI = XSDEditorPlugin.getPlugin().getXMLSchemaTargetNamespace();
    element.setAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE, defaultTargetURI);
    element.setAttribute("xmlns:" + defaultPrefixForTargetNamespace, defaultTargetURI);
    
    document.appendChild(element);
  }
  
  public void buildXSDModel()
  {
    try
    {
      Document document  = ((IDOMModel)getModel()).getDocument();
      if (document.getChildNodes().getLength() == 0)
      {
        // this is an empty document.  Create a default schema tag now
        createDefaultSchemaNode();
      }

      createSchema(document.getDocumentElement());

			XSDDocumentAdapter documentAdapter =
				new XSDDocumentAdapter(((IDOMModel)getModel()).getDocument());
    }
    catch (Exception e)
    {
//      XSDEditorPlugin.getPlugin().getMsgLogger().write("Failed to create Model");
//      XSDEditorPlugin.getPlugin().getMsgLogger().write(e);
//      e.printStackTrace();
    }



//      XSDResourceFactoryImpl.validate(xsdSchema, input.getFile().getContents(true));
  }

//  private void updateParentForDerivation(Node node, XSDConcreteComponent correspondingComponent)
//  {
//    if (XSDDOMHelper.inputEquals(node, XSDConstants.SIMPLECONTENT_ELEMENT_TAG, false)||
//        XSDDOMHelper.inputEquals(node,XSDConstants.COMPLEXCONTENT_ELEMENT_TAG,false))
//    {
//      XSDComplexTypeDefinition xsdComplexTypeDefinition =
//        correspondingComponent.getContainer() instanceof XSDComplexTypeDefinition ? 
//          (XSDComplexTypeDefinition)correspondingComponent.getContainer() :
//          null;
//      if (xsdComplexTypeDefinition != null)
//      {
//        xsdComplexTypeDefinition.elementContentsChanged(xsdComplexTypeDefinition.getElement());
//      }
//    }
//  }    

//  private void checkUnion(Node node, XSDConcreteComponent correspondingComponent, int i)
//  {
//    // bug 219967 - union changes to restriction
//    if (XSDDOMHelper.inputEquals(node, XSDConstants.UNION_ELEMENT_TAG, false))
//    {
////      XSDConcreteComponent comp = correspondingComponent.getContainer();
////      if (comp != null)
////      {
////        switch (i)
////        {
////          case 1:
////            comp.elementAttributesChanged((Element)node);
////            break;
////          case 4:
////            comp.elementContentsChanged((Element)node);
////            break;
////        }
////      }
//    }
//    else
//    {
//      switch (i)
//      {
//        case 1:
//        case 4:
//          // do both types of updates since sometimes the attributes have changed indirectly
//          // because the content has changed
//          correspondingComponent.elementAttributesChanged((Element)node);
//          correspondingComponent.elementContentsChanged((Element)node);
//          break;
//      }
//    }
//  }
  
//  private void updateMap(XSDConcreteComponent listener, Element documentElement)
//  {
//    boolean handleChangeInSchema = false;
//    if (listener instanceof XSDSchema)
//    {
//      if (!handleChangeInSchema)
//      {
//        handleChangeInSchema = true;
//        XSDSchema xsdSchema = (XSDSchema)listener;
//        java.util.Map prefixToNameSpaceMap = xsdSchema.getQNamePrefixToNamespaceMap();
//        String targetNamespace = xsdSchema.getTargetNamespace();
////        System.out.println("targetNamespace = " + targetNamespace);
//
//        NamedNodeMap attributes = documentElement.getAttributes();
//        int length = attributes.getLength();
//        
//        ArrayList keyList = new ArrayList();
//        keyList.addAll(prefixToNameSpaceMap.keySet());
//        
//        String key;
//
//
//        // update the map when the prefix is changed
//        CHECK: for (int i = 0; i < length; i++)
//        {
//          Attr attr = (Attr)attributes.item(i);
//          String name = attr.getNodeName();
//          
//          if (isValidXMLNSAttribute(name))
////          if (name.startsWith("xmlns"))
//          {
//            String value = attr.getNodeValue();
//            if (value == null)
//            {
//              break CHECK;
//            }
//            int index = name.indexOf(":");
//            key  = index == -1 ? null : name.substring(index + 1);
////            System.out.println(" Attribute key is " + key + " , value = " + value);
////            System.out.println("   map.get(key) = " + prefixToNameSpaceMap.get(key));
//            if (!prefixToNameSpaceMap.containsKey(key))
//            {
//              for (Iterator iter = keyList.iterator(); iter.hasNext(); )
//              {
//                String aPrefix = (String)iter.next();
////                System.out.println("    --> A Map Prefix is " + aPrefix);
////                System.out.println("    --> model map.get(prefix) " + prefixToNameSpaceMap.get(aPrefix));
//                if (prefixToNameSpaceMap.get(aPrefix) != null)
//                {
//                  if (prefixToNameSpaceMap.get(aPrefix).equals(value))
//                  {
//                    prefixToNameSpaceMap.remove(aPrefix);
//                  }
//                }
//              }
//            }
//            else if (prefixToNameSpaceMap.containsKey(key))
//            {
//              if (prefixToNameSpaceMap.get(key) != null)
//              {
//                if (!prefixToNameSpaceMap.get(key).equals(value))
//                {
//                  Set entrySet = prefixToNameSpaceMap.entrySet();
//                  for (Iterator iter = entrySet.iterator(); iter.hasNext(); )
//                  {
//                    Map.Entry aMapEntry = (Map.Entry)iter.next();
//                    if (  (key != null && (aMapEntry.getKey() != null && aMapEntry.getKey().equals(key)))
//                           || (key == null && (aMapEntry.getKey() == null)))
//                    {
//                      aMapEntry.setValue(value);
//                    }
//                  }
//                }
//              }
//              else
//              {
//                Set entrySet = prefixToNameSpaceMap.entrySet();
//                for (Iterator iter = entrySet.iterator(); iter.hasNext(); )
//                {
//                  Map.Entry aMapEntry = (Map.Entry)iter.next();
//                  if (  (key != null && (aMapEntry.getKey() != null && aMapEntry.getKey().equals(key)))
//                         || (key == null && (aMapEntry.getKey() == null)))
//                  {
//                    aMapEntry.setValue(value);
//                  }
//                }
//              }
//            }
//          }
//        }
//        
//        boolean modelMapPrefixFound = false;
//        for (Iterator iter = keyList.iterator(); iter.hasNext(); )
//        {
//          String aPrefix = (String)iter.next();
//          modelMapPrefixFound = false;
//          attributes = documentElement.getAttributes();
//          length = attributes.getLength();
//
//          for (int i = 0; i < length; i++)
//          {
//            Attr attr = (Attr)attributes.item(i);
//            if (attr != null)
//            {
//              String name = attr.getNodeName();
//            
//              // if (name.startsWith("xmlns"))
//              if (isValidXMLNSAttribute(name))
//              {
//                String value = attr.getNodeValue();
//                int index = name.indexOf(":");
//                key  = index == -1 ? null : name.substring(index + 1);
//                if (aPrefix == null && key == null)
//                {
//                  modelMapPrefixFound = true;
//                }
//                else if (aPrefix != null && (aPrefix.equals(key)))
//                {
//                  modelMapPrefixFound = true;
//                  if ((prefixToNameSpaceMap.get(key) != null && !prefixToNameSpaceMap.get(key).equals(value))
//                       || (prefixToNameSpaceMap.get(key) == null && value != null))
//                  {
//                    if (value != null && value.length() > 0)
//                    {
//                      prefixToNameSpaceMap.put(aPrefix, value);
//                    }
//                  }
//                }
//                else if (key != null && (key.equals(aPrefix)))
//                {
//                  modelMapPrefixFound = true;
//                }
//              }
//            }
//          }
//          if (!modelMapPrefixFound)
//          {
//            prefixToNameSpaceMap.remove(aPrefix);
//          }
//        }
//       
//        // to ensure map is recreated
////        XSDSchemaHelper.updateElement(xsdSchema);        
////        reparseSchema();
//
//        handleChangeInSchema = false;
//
////        System.out.println("XSDeditor Map is " + prefixToNameSpaceMap.values());
////        System.out.println("XSDeditor Map keys are " + prefixToNameSpaceMap.keySet());
//        
//      }
//    }
//  }

  /**
   * Returns the xsdSchema.
   * @return XSDSchema
   */
  public XSDSchema getXSDSchema()
  {
    return xsdSchema;
  }


  /**
   * Returns the resourceFile.
   * @return IFile
   */
  public IFile getFileResource()
  {
    return resourceFile;
  }

  /**
   * Get the IDocument from the text viewer
   */
  public IDocument getEditorIDocument()
  {
    IDocument document = textEditor.getTextViewer().getDocument();
    return document;
  }

  /**
   * Create ref integrity tasks in task list
   */
  public void createTasksInTaskList(ArrayList messages)
  {
//    DisplayErrorInTaskList tasks = new DisplayErrorInTaskList(getEditorIDocument(), getFileResource(), messages);
//    tasks.run();
  }

  public void resetInformationTasks()
  {
// DisplayErrorInTaskList.removeInfoMarkers(getFileResource());
  }
  
  public XSDGraphViewer getGraphViewer()
  {
    return graphViewer;
  }

//  /**
//   * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
//   */
//  protected void handlePropertyChange(int propertyId)
//  {
//    super.handlePropertyChange(propertyId);
//    
//    if (propertyId == IEditorPart.PROP_INPUT)
//    {
//      setInput(textEditor.getEditorInput());
//      resourceFile = ((IFileEditorInput) getEditorInput()).getFile();
//      setTitle(resourceFile.getName());
////      outline.setModel(getModel());
//
//      // even though we've set title etc., several times already!
//      // only now is all prepared for it.
//      firePropertyChange(IWorkbenchPart.PROP_TITLE);
//      firePropertyChange(PROP_DIRTY);
//    }
//    else if (propertyId == IEditorPart.PROP_TITLE)
//    {
//      if (getEditorInput() != textEditor.getEditorInput())
//      {
//        setInput(textEditor.getEditorInput());
//      }
//    }    
//  }

  public IEditorPart getActiveEditorPage()
  {
    return getActiveEditor();
  }
  
  public XSDTextEditor getXSDTextEditor()
	{
    return textEditor;
  }

	class InternalPartListener implements IPartListener
	{
	  XSDEditor editor;
	  public InternalPartListener(XSDEditor editor)
	  {
	    this.editor = editor; 
	  }
	  
		public void partActivated(IWorkbenchPart part)
		{
			if (part == editor)
			{
        ISelection selection = getSelectionManager().getSelection();
        if (selection != null)
        {
          if (getCurrentPageType().equals(XSDEditorPlugin.GRAPH_PAGE))
          {
            getSelectionManager().selectionChanged(new SelectionChangedEvent(editor.getGraphViewer().getComponentViewer(), selection));
          }
          else if (getCurrentPageType().equals(XSDEditorPlugin.SOURCE_PAGE))
          {
            getSelectionManager().setSelection(selection);
          }
        }
			}
		}

		public void partBroughtToTop(IWorkbenchPart part)
		{
		}

		public void partClosed(IWorkbenchPart part)
		{
		}

   
		public void partDeactivated(IWorkbenchPart part)
		{
		}

		public void partOpened(IWorkbenchPart part)
		{
		}
	}
  
}
