package brn.gui.linktable.diagram.custom.editors;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.draw2d.DelegatingLayout;
import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.LayeredPane;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;

import brn.gui.Activator;
import brn.gui.datasource.Source;
import brn.gui.diagram.SimulatorDocumentProvider;
import brn.gui.diagram.SimulatorResource;
import brn.gui.editors.SimulatorItemInput;
import brn.gui.linktable.diagram.custom.edit.parts.ModelEditPartFactory;

public class LinkTableDiagramEditor extends DiagramDocumentEditor
  implements IPropertyChangeListener {

  public static final String ID = "brn.gui.linktable.diagram.custom.editors.LinkTableDiagramEditor"; //$NON-NLS-1$

  private static final int REFRESH_DELAY = 1000 /* ms */;

  private RefreshTimer timer;  //  @jve:decl-index=0:


  public LinkTableDiagramEditor() {
    super(true);

    timer = new RefreshTimer();
  }

  protected String getEditingDomainID() {
    return "brn.gui.linktable.diagram.EditingDomain"; //$NON-NLS-1$
  }

//  protected TransactionalEditingDomain createEditingDomain() {
//    TransactionalEditingDomain domain = super.createEditingDomain();
//    domain.setID(getEditingDomainID());
//    return domain;
//  }

  protected void setDocumentProvider(IEditorInput input) {
    setDocumentProvider(new SimulatorDocumentProvider());
  }

  protected void configureGraphicalViewer() {
    super.configureGraphicalViewer();
    DiagramRootEditPart root = (DiagramRootEditPart) getDiagramGraphicalViewer()
        .getRootEditPart();
    LayeredPane printableLayers = (LayeredPane) root
        .getLayer(LayerConstants.PRINTABLE_LAYERS);
    FreeformLayer extLabelsLayer = new FreeformLayer();
    extLabelsLayer.setLayoutManager(new DelegatingLayout());
    printableLayers.addLayerAfter(extLabelsLayer,
        ModelEditPartFactory.EXTERNAL_NODE_LABELS_LAYER,
        LayerConstants.PRIMARY_LAYER);
    LayeredPane scalableLayers = (LayeredPane) root
        .getLayer(LayerConstants.SCALABLE_LAYERS);
    FreeformLayer scaledFeedbackLayer = new FreeformLayer();
    scaledFeedbackLayer.setEnabled(false);
    scalableLayers.addLayerAfter(scaledFeedbackLayer,
        LayerConstants.SCALED_FEEDBACK_LAYER,
        DiagramRootEditPart.DECORATION_UNPRINTABLE_LAYER);

    LinkTableResouce resource =
      (LinkTableResouce) getEditorInput().getAdapter(Resource.class);
    resource.getSimulator().addPropertyChangeListener(this);

    timer.start();
  }

  @Override
  public void dispose() {
    if (null != timer)
      timer.stop();

    SimulatorResource resource =
      (SimulatorResource) getEditorInput().getAdapter(Resource.class);
    if (null != resource.getSimulator())
      resource.getSimulator().removePropertyChangeListener(this);

    super.dispose();
  }

  public class RefreshTimer implements Runnable {
    private boolean stop = false;
    public void run() {
      refresh();
      if (!stop)
        start();
    }
    public void start() {
      this.stop = false;
      getEditorSite().getShell().getDisplay().timerExec(REFRESH_DELAY, timer);
    }
    public void stop() {
      this.stop = true;
    }
    public boolean isRunning() {
      return !stop;
    }
  }

  public void refresh() {
    if (!getEditorSite().getPage().isPartVisible(getSite().getPart()))
      return;

    LinkTableResouce resource =
      (LinkTableResouce) getEditorInput().getAdapter(Resource.class);

    try {
      resource.refresh();
    } catch (CoreException e) {
      Activator.log(e);
      timer.stop();
      close();
    }
  }

  /**
   * Closes the editor programmatically.
   */
  public void close() {
    Display display = getSite().getShell().getDisplay();
    display.asyncExec(new Runnable() {
            public void run() {
                getSite().getPage().closeEditor(LinkTableDiagramEditor.this, false);
            }
        });
  }

  public void propertyChange(PropertyChangeEvent event) {
    if (event.getProperty().equals(Source.CONNECTED)
        ||event.getProperty().equals(Source.DATASOURCE_CREATED)
        ||event.getProperty().equals(Source.DATASOURCE_DISPOSED)) {
      IEditorInput editorInput = getEditorInput();
      if (null == editorInput)
        return;

      LinkTableResouce resource =
        (LinkTableResouce) editorInput.getAdapter(Resource.class);
      if (null == resource.getSimulator()
          ||!resource.getSimulator().isConnected()) {
        if (null != resource.getSimulator())
          resource.getSimulator().removePropertyChangeListener(this);
        close();
      }
    }
  }

}
