/*------------------------------------------------------------------------------
Copyright (c)2000 TogetherSoft Corporation. Patents pending. All rights reserved.
------------------------------------------------------------------------------*/

package com.togethersoft.modules.inspector;

import com.togethersoft.openapi.ide.IdeStartup;
import com.togethersoft.openapi.ide.IdeContext;
import com.togethersoft.openapi.ide.inspector.*;
import com.togethersoft.openapi.ide.inspector.util.*;
import com.togethersoft.openapi.ide.inspector.util.property.*;
import com.togethersoft.openapi.ide.inspector.util.table.*;
import com.togethersoft.openapi.ide.inspector.util.editors.*;
import com.togethersoft.openapi.ide.util.*;
import com.togethersoft.openapi.rwi.*;
import com.togethersoft.openapi.ide.IdeAccess;

import com.togethersoft.openapi.ide.window.IdeSelectorDialogType;
import javax.swing.DefaultComboBoxModel;
import com.togethersoft.openapi.util.RwiElementsUtil;

import java.io.*;

/**
 * @author TogetherSoft
 */
public class ObjectInspector implements IdeStartup, IdeInspectorBuilder {
  public void autorun(){
    IdeInspectorManager manager = IdeInspectorManagerAccess.getInspectorManager();
    manager.addInspectorBuilder(this);
  }
  public IdeInspector buildInspector(IdeContext context, IdeInspector inspector) {
    if (!RwiElementsUtil.checkProperty(context, RwiProperty.SHAPE_TYPE, RwiShapeType.OBJECT))
      return inspector;
    RwiElement[] rwiElements = RwiElementsUtil.getRwiElements(context);
    RwiReference[] rwiReferences = RwiElementsUtil.getRwiReferences(context);

    IdeInspectorComponent propertiesComponent = inspector.findComponent("Properties");
    IdeInspectorPropertySetComponent propertiesPage = null;
    if (propertiesComponent == null) {
      propertiesComponent = new ObjectPropertiesComponent(context, rwiElements);
      if (propertiesComponent instanceof IdeInspectorPropertySetComponent) {
        propertiesPage = (IdeInspectorPropertySetComponent)propertiesComponent;
      }
      inspector.addComponent(propertiesPage, null, ComponentWeight.PROPERTIES);
    }

    if (rwiReferences != null) InspectorUtils.createViewPage (context, inspector, rwiReferences);
    if (rwiElements.length == 1) {
      InspectorUtils.createDescriptionPage (context, inspector, rwiElements);
      inspector.addComponent(new DocComponent(rwiElements[0]), null, ComponentWeight.HTMLDOC);
      InspectorUtils.createReqPage (context, inspector, rwiElements);

      IdeInspectorComponent classComponent = inspector.findComponent("Class");
      if ( classComponent == null ) {
        classComponent = new ClassComponent(context, rwiElements[0]);
        inspector.addComponent(classComponent, new Condition() {
          public boolean execute(IdeContext context) {
            return RwiElementsUtil.checkProperty(context, "$instantiatedClass", true);
          }
        }, ComponentWeight.MEMBER);
      }
    }

    return inspector;
  }
}

class ObjectPropertiesComponent extends IdeInspectorPropertySetComponent {
  public ObjectPropertiesComponent (IdeContext context, RwiElement[] rwiElements) {
    super(context);
    myRwiElements = rwiElements;
    setName("Properties");
    setService(UIComponentService.class, new PropertyTableComponentUI(this));
  }

  public void update() {
    IdeInspectorProperty[] properties = getProperties();
    for (int i = 0; i < properties.length; i++) {
      removeProperty(properties[i]);
    }
    refill();
    super.update();
  }

  private void refill() {
    IdeInspectorProperty property;

    if (myRwiElements.length == 1) {
      property = new RwiInspectorStringProperty(myRwiElements, "$objectName");
      property.setName("name");
      addProperty(property, null);
    }

    property = new RwiInspectorStringProperty(myRwiElements, "stereotype");
    SwingComboBoxEditor editor = new SwingComboBoxEditor(
      new DefaultComboBoxModel(
        new String[] {
          "actor", "Database"
        }
      )
    );
    editor.setValueEditable(true);
    property.setPropertyEditor(editor);
    addProperty(property, null);

    property = new RwiInspectorStringProperty(myRwiElements[0], "$instantiates");
    property.setName("instantiates");
    property.setPropertyEditor(new SingleElementChooserEditor(myRwiElements[0], IdeSelectorDialogType.INSTANTIATES));
    addProperty(property, null);

    property = new RwiInspectorStringProperty(myRwiElements, "persistence");
    editor = new SwingComboBoxEditor(
      new DefaultComboBoxModel(
        new String[] {
          "transient", "static", "persistent"
        }
      )
    );
    editor.setValueEditable(true);
    property.setPropertyEditor(editor);
    addProperty(property, null);

    property = new RwiInspectorBooleanProperty(myRwiElements, "concurrent");
    property.setName("concurrent");
    addProperty(property, null);

    property = new RwiInspectorBooleanProperty(myRwiElements, "active");
    property.setName("active");
    addProperty(property, null);

    property = new RwiInspectorBooleanProperty(myRwiElements, "multipleInstance");
    property.setName("multiple instance");
    addProperty(property, null);

    property = new RwiInspectorStringProperty(myRwiElements, "state");
    property.setName("state");
    addProperty(property, null);
  }

  private RwiElement[] myRwiElements;
}
/*
class InstantiatedClassComponent extends IdeInspectorPropertySetComponent {
  public InstantiatedClassComponent(IdeContext context, RwiElement objectElement) {
    super(context);
    myObjectElement = objectElement;
    setName("Class");
    setService(UIComponentService.class, new PropertyTableComponentUI(this));
  }

  public void update() {
    IdeInspectorProperty[] properties = getProperties();
    for (int i=0;i<properties.length;i++) {
      removeProperty(properties[i]);
    }
    refill();
    super.update();
  }

  private void refill(){
    String instantiatedClassUniqueName = myObjectElement.getProperty("$instantiatedClass");
    myClassElement = RwiModelAccess.getModel().findElement(instantiatedClassUniqueName);

    IdeInspectorProperty property;

    property = new RwiInspectorStringProperty(myClassElement, RwiProperty.NAME);
    property.setName("name");
    addProperty(property, null);

    if (RwiElementsUtil.checkProperty(myContext, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      if (myClassElement instanceof RwiNode) {
        String packageName = ((RwiNode)myClassElement).getContainingPackage().getProperty(RwiProperty.FULL_NAME);
        if (packageName.length() == 0) {
          packageName = "<default>";
        }
        property = new ReadOnlyProperty(packageName, String.class);
        property.setName("package");
        addProperty(property, null);
      }
    }

    property = new RwiInspectorStringProperty(myClassElement, "stereotype");
    SwingComboBoxEditor editor = new SwingComboBoxEditor(
      new DefaultComboBoxModel(
        new String[] {
          "role", "container", "moment-interval", "mi-detail", "party", "place",
          "thing", "description", "abstractfactory", "factory", "actor", "metaclass",
          "utility", "visitor", "plug-in point", "thread", "type", "implementationClass",
          "interface", "powertype", "process", "stereotype", "Idl-Interface",
          "struct", "union", "enumeration", "exception", "Boundary", "Entity"
        }
      )
    );
    editor.setValueEditable(true);
    property.setPropertyEditor(editor);
    addProperty(property, null);

    property = new RwiInspectorStringProperty(myClassElement, "alias");
    property.setName("alias");
    addProperty(property, null);

    property = new FileNameProperty(myClassElement, RwiProperty.FILE, "file");
    addProperty(property, null);

    if (RwiElementsUtil.checkProperty(myContext, RwiProperty.LANGUAGE, RwiLanguage.CPP)) {
      String definitionFileName = myClassElement.getProperty(RwiProperty.DEFINITION_FILE);
      final IdeInspectorProperty defFileProperty = new FileNameProperty(myClassElement, RwiProperty.DEFINITION_FILE, "definition file");
      addProperty(defFileProperty, new Condition(){
        public boolean execute(IdeContext context){
          return defFileProperty.getValue() != null;
        }
      });

      property = new RwiInspectorStringProperty(myClassElement, RwiProperty.NAMESPACE);
      property.setName("namespace");
      addProperty(property, null);

      property = new RwiInspectorMultipleStringProperty(myClassElement, RwiProperty.EXTENDS);
      property.setName("extends");
      property.setPropertyEditor(new RwiPropertyMultiValueElementChooserEditor(myClassElement, RwiProperty.EXTENDS, IdeSelectorDialogType.CPP_EXTENDS));
      addProperty(property, null);
    } else if (RwiElementsUtil.checkProperty(myContext, RwiProperty.LANGUAGE, RwiLanguage.IDL)) {
      property = new RwiInspectorStringProperty(myClassElement, RwiProperty.NAMESPACE);
      property.setName("module");
      addProperty(property, null);

      property = new RwiInspectorMultipleStringProperty(myClassElement, RwiProperty.EXTENDS);
      property.setName("extends");
      property.setPropertyEditor(new RwiPropertyMultiValueElementChooserEditor(myClassElement, RwiProperty.EXTENDS, IdeSelectorDialogType.IDL_EXTENDS));
      addProperty(property, null);

      property = new RwiInspectorMultipleStringProperty(myClassElement, RwiProperty.IMPLEMENTS);
      property.setName("implements");
      property.setPropertyEditor(new RwiPropertyMultiValueElementChooserEditor(myClassElement, RwiProperty.IMPLEMENTS, IdeSelectorDialogType.IDL_IMPLEMENTS));
      addProperty(property, null);
    }

    if (RwiElementsUtil.checkProperty(myContext, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      if (((RwiNode)myClassElement).getContainingNode() == null) {
        if (!myClassElement.hasProperty(RwiProperty.INTERFACE)) {
          property = new RwiInspectorBooleanProperty(myClassElement, RwiProperty.PUBLIC);
          property.setName("public");
          addProperty(property, null);
        }
      } else {
        property = new RwiInspectorVisibilityProperty(myClassElement);
        editor = new SwingComboBoxEditor(
          new DefaultComboBoxModel(
            new String[] {
              "public", "protected", "package local", "private"
            }
          )
        );
        property.setPropertyEditor(editor);
        property.setDisplayName("visibility");
        addProperty(property, null);

        property = new RwiInspectorBooleanProperty(myClassElement, RwiProperty.STATIC);
        property.setName("static");
        addProperty(property, null);
      }

      if (RwiElementsUtil.checkProperty(myContext, RwiProperty.INTERFACE, false)) {
        property = new RwiInspectorBooleanProperty(myClassElement, RwiProperty.ABSTRACT);
        property.setName("abstract");
        addProperty(property, null);
      }

      property = new RwiInspectorMultipleStringProperty(myClassElement, RwiProperty.EXTENDS);
      property.setValue(IdeInspectorProperty.MULTI_VALUE_TAG, Boolean.FALSE); //although it's represented by multivalue property, it takes only one value
      property.setName("extends");
      property.setPropertyEditor(new RwiPropertyMultiValueElementChooserEditor(myClassElement, RwiProperty.EXTENDS, IdeSelectorDialogType.JAVA_EXTENDS));
      addProperty(property, null);

      if (RwiElementsUtil.checkProperty(myContext, RwiProperty.INTERFACE, false)) {
        property = new RwiInspectorMultipleStringProperty(myClassElement, RwiProperty.IMPLEMENTS);
        property.setName("implements");
        property.setPropertyEditor(new RwiPropertyMultiValueElementChooserEditor(myClassElement, RwiProperty.IMPLEMENTS, IdeSelectorDialogType.JAVA_IMPLEMENTS));
        addProperty(property, new Condition() {
          public boolean execute(IdeContext context) {
            return RwiElementsUtil.checkProperty(context, RwiProperty.INTERFACE, false);
          }
        });
      }

      property = new RwiInspectorBooleanProperty(myClassElement, RwiProperty.INTERFACE);
      property.setName("interface");
      addProperty(property, null);

      property = new RwiInspectorStringProperty(myClassElement, "invariants");
      property.setDisplayName("invariants");
      property.setPropertyEditor(new ExtendedStringEditor("invariants"));
      addProperty(property, null);
    }

    property = new RwiInspectorBooleanProperty(myClassElement, "persistent");
    property.setName("persistent");
    addProperty(property, null);
  }
  private RwiElement myObjectElement;
  private RwiElement myClassElement;
}
*/
