/*----------------------------------------------------------------------------
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.window.IdeSelectorDialogType;
import javax.swing.DefaultComboBoxModel;
import com.togethersoft.openapi.util.RwiElementsUtil;

/**
 * @author TogetherSoft
 */
public class AttributeInspector 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.ATTRIBUTE))
      return inspector;
    RwiElement[] rwiElements = RwiElementsUtil.getRwiElements(context);
    RwiReference[] rwiReferences = RwiElementsUtil.getRwiReferences(context);

    IdeInspectorComponent propertiesComponent = inspector.findComponent("Properties");
    IdeInspectorPropertySetComponent propertiesPage;
    if (propertiesComponent instanceof IdeInspectorPropertySetComponent) {
      propertiesPage = (IdeInspectorPropertySetComponent)propertiesComponent;
    }
    else {
      propertiesPage = new IdeInspectorPropertySetComponent(context);
      propertiesPage.setName("Properties");
      propertiesPage.setService(UIComponentService.class, new PropertyTableComponentUI(propertiesPage));
      inspector.addComponent(propertiesPage, null, ComponentWeight.PROPERTIES);
    }

    IdeInspectorProperty property;

    if (rwiElements.length == 1) {
      property = new RwiInspectorStringProperty(rwiElements, RwiProperty.NAME);
      property.setName("name");
      propertiesPage.addProperty(property, null);
    }

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

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

    if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      property = new RwiInspectorStringProperty(rwiElements, RwiProperty.TYPE) {
        public boolean canSetValue(Object value){
          if ( "void".equals(String.valueOf(value)) ) return false;
          return super.canSetValue(value);
        }
      };
      editor = new SwingComboBoxEditor(
        new DefaultComboBoxModel(
          new String[] {
            "boolean", "byte", "char", "double", "float", "int", "long",
            "short", "String", "java.util.Vector", "java.util.Hashtable"
          }
        )
      );
      editor.setValueEditable(true);
      property.setName("type");
      property.setPropertyEditor(editor);
      propertiesPage.addProperty(property, null);
    } else if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.CPP)) {
      property = new RwiInspectorStringProperty(rwiElements, RwiProperty.DEFINITION_FILE);
      property.setDisplayName("definition file");
      property.setPropertyEditor(new ExtendedFileNameEditor("open"));
      propertiesPage.addProperty(property, new Condition(){
        public boolean execute(IdeContext context){
          return RwiElementsUtil.checkProperty(context, RwiProperty.STATIC, true);
        }
      });

      property = new RwiInspectorStringProperty(rwiElements, RwiProperty.TYPE){
        public boolean canSetValue(Object value){
          if ( "void".equals(String.valueOf(value)) ) return false;
          return super.canSetValue(value);
        }
      };
      editor = new SwingComboBoxEditor(
        new DefaultComboBoxModel(
          new String[] {
            "bool", "char", "double", "float", "int", "long", "long double",
            "short", "unsigned", "unsigned long", "unsigned short", "string"
          }
        )
      );
      editor.setValueEditable(true);
      property.setDisplayName("type");
      property.setPropertyEditor(editor);
      propertiesPage.addProperty(property, null);
    } else if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.IDL)) {
      property = new RwiInspectorStringProperty(rwiElements, RwiProperty.TYPE){
        public boolean canSetValue(Object value){
          if ( "void".equals(String.valueOf(value)) ) return false;
          return super.canSetValue(value);
        }
      };
      editor = new SwingComboBoxEditor(
        new DefaultComboBoxModel(
          new String[] {
            "float", "double", "long double", "long", "long long", "short",
            "unsigned long", "unsigned long long", "unsigned short", "char",
            "wchar", "boolean", "octet", "any"
          }
        )
      );
      editor.setValueEditable(true);
      property.setDisplayName("type");
      property.setPropertyEditor(editor);
      propertiesPage.addProperty(property, null);
    }

    property = new RwiInspectorStringProperty(rwiElements[0], RwiProperty.ASSOCIATES);
    property.setName("associates");
    property.setPropertyEditor(new SingleElementChooserEditor(rwiElements[0], IdeSelectorDialogType.ASSOCIATES));
    propertiesPage.addProperty(property, null);

    if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.CPP)) {
        property = new RwiInspectorStringProperty(rwiElements, RwiProperty.INITIAL_VALUE);
        property.setName("initial value");
        propertiesPage.addProperty(property, new Condition() {
            public boolean execute(IdeContext context) {
              return (RwiElementsUtil.checkProperty(context, RwiProperty.STATIC, true));
            }
        });
    } else if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      final RwiElement[] finalRwiElements = rwiElements;
      property = new RwiInspectorStringProperty(finalRwiElements, RwiProperty.INITIAL_VALUE){
        public boolean canSetValue(Object value){
          RwiMember attribute = (RwiMember)finalRwiElements[0];
          RwiNode containingNode = attribute.getContainingNode();
          if ( containingNode == null || !containingNode.hasProperty(RwiProperty.INTERFACE) ) return super.canSetValue(value);
          if ( value instanceof String && "".equals(((String)value).trim()) ) {
            return false;
          } else {
            return super.canSetValue(value);
          }
        }
      };
      property.setName("initial value");
      propertiesPage.addProperty(property, null);
    }

    if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      boolean interfaceMember = false;
      for (int i = 0; i < rwiElements.length; i++) {
        if (((RwiMember)rwiElements[i]).getContainingNode().hasProperty(RwiProperty.INTERFACE)) {
          interfaceMember = true;
          break;
        }
      }
      if (!interfaceMember) {
        property = new RwiInspectorVisibilityProperty(rwiElements);
        editor = new SwingComboBoxEditor(
          new DefaultComboBoxModel(
            new String[] {
              "public", "protected", "package local", "private"
            }
          )
        );
        property.setPropertyEditor(editor);
        property.setDisplayName("visibility");
        propertiesPage.addProperty(property, null);

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

        final RwiElement[] finalRwiElements = rwiElements;
        property = new RwiInspectorBooleanProperty(rwiElements, RwiProperty.FINAL) {
          public boolean canSetValue(Object value) {
            for (int i = 0; i < finalRwiElements.length; i++) {
              if (finalRwiElements[i].hasProperty(RwiProperty.VOLATILE))
                return false;
            }
            return true;
          }
        };
        property.setName("final");
        propertiesPage.addProperty(property, null);

        property = new RwiInspectorBooleanProperty(rwiElements, RwiProperty.TRANSIENT);
        property.setName("transient");
        propertiesPage.addProperty(property, null);

        property = new RwiInspectorBooleanProperty(rwiElements, RwiProperty.VOLATILE) {
          public boolean canSetValue(Object value) {
            for (int i = 0; i < finalRwiElements.length; i++) {
              if (finalRwiElements[i].hasProperty(RwiProperty.FINAL))
                return false;
            }
            return true;
          }
        };
        property.setName("volatile");
        propertiesPage.addProperty(property, null);
      }
    }
    else if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.CPP)) {
      property = new RwiInspectorVisibilityProperty(rwiElements);
      editor = new SwingComboBoxEditor(
        new DefaultComboBoxModel(
          new String[] {
            "public", "protected", "private"
          }
        )
      );
      property.setPropertyEditor(editor);
      property.setDisplayName("visibility");
      propertiesPage.addProperty(property, null);

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

    IdeInspectorComponent javadocComponent = inspector.findComponent("Javadoc");
    IdeInspectorPropertySetComponent javadocPage;
    if (javadocComponent instanceof IdeInspectorPropertySetComponent) {
      javadocPage = (IdeInspectorPropertySetComponent)javadocComponent;
    } else {
      javadocPage = new IdeInspectorPropertySetComponent(context);
      javadocPage.setName("Javadoc");
      javadocPage.setService(UIComponentService.class, new PropertyTableComponentUI(javadocPage));
      inspector.addComponent(javadocPage, null, ComponentWeight.JAVADOC);
    }

    // Javadoc tags

    if (rwiElements.length == 1) InspectorUtils.createDescriptionPage (context, inspector, rwiElements);

    if (RwiElementsUtil.checkProperty(context, RwiProperty.LANGUAGE, RwiLanguage.JAVA)) {
      property = new RwiInspectorStringProperty(rwiElements, "deprecated");
      property.setDisplayName("@deprecated");
      javadocPage.addProperty(property, null);

      property = new RwiInspectorMultipleStringProperty(rwiElements, "see");
      property.setDisplayName("@see");
      javadocPage.addProperty(property, null);
    }

    property = new RwiInspectorStringProperty(rwiElements, "since");
    property.setDisplayName("@since");
    javadocPage.addProperty(property, null);

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

    return inspector;
  }
}

