/*******************************************************************************
 * 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 = "";
	  
	  Resource resource = null;
      // If the resource is in the workspace....
      // otherwise the user is trying to open an external file
      if (resourceFile != null)
      {
        pathName = resourceFile.getFullPath().toString();
		
		if (resourceFile.exists())
		{
          resource = resourceSet.getResource(URI.createPlatformResourceURI(pathName), true);
		}
        else  
		{
          // get resource from File URI.  This happens when we try to open the imported schema
		  // from the importing schema that was opened via the Open External File action.
		  resource = resourceSet.getResource(URI.createFileURI(pathName), true);
		}
      }
      else
      {
		// This is the case where open external xsd file is attempted
        IEditorInput input = getEditorInput();	  
		if (input instanceof JavaFileEditorInput) // for some reason it is a JavaFileEditorInput
		{
		  IPath path = ((JavaFileEditorInput)input).getPath(input);
          URI uri = URI.createFileURI(path.toString());
	      resource = resourceSet.getResource(uri, true);
		}
      }
	  
	  if (resource != null)
	  {
		resourceSet.getResources().add(resource);
	      
	    Object obj = resource.getContents().get(0);
	    if (obj instanceof XSDSchema)
	    {
	      xsdSchema = (XSDSchema)obj;
	    }
	 
	    xsdSchema.setElement((Element)node);
	    resource.setModified(false);
	  }
	}
    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)
		{
		}
	}
  
}
