/*******************************************************************************
 * Copyright (c) 2004, 2005 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.text;

import org.eclipse.swt.widgets.Display;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDSchema;
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;

public class XSDModelReconcileAdapter extends DocumentAdapter
{
    INodeNotifier currentNotifier;
    int currentEventType;
    XSDSchema schema;
    
    public XSDModelReconcileAdapter(Document document, XSDSchema schema)
    {
      super(document);
      this.schema = schema;
    }
        
    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 = schema.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))
              {
                schema.reset();
                schema.update();
              }
            }
          }          
        }
        case INodeNotifier.CHANGE:
        {
          Node node = (Node)notifier;
          XSDConcreteComponent listener = schema.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 = schema.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);
                schema.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
{
  Document document;
  
  public DocumentAdapter(Document document)
  {
    this.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);
}