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

package com.togethersoft.modules.xmleditor.xmltree;

import java.util.*;
import javax.swing.*;

import java.beans.PropertyEditor;
import com.togethersoft.openapi.ide.inspector.util.editors.*;
import com.togethersoft.modules.xmleditor.dtd.*;

import com.togethersoft.together.util.message.Informator;
import com.togethersoft.together.util.message.DefaultInformatorImpl;


abstract public class ValueHolder
{
  /**
   * @supplierCardinality 1 
   */
  private XMLTreeManager m_xmlTreeManager;

  private DTDValueDef m_valueDef;

  private Object  m_value;
  private Class   m_typeClass;

  private Class   m_editorClass = null;
  private PropertyEditor m_editor = null;

  //--------------------------------------------------------------------
  public ValueHolder (XMLTreeManager xmlTreeManager, DTDValueDef valueDef)
  {
    m_xmlTreeManager = xmlTreeManager;
    m_valueDef = valueDef;
    setStringValue (valueDef.getDefaultValue());
  }

  //--------------------------------------------------------------------
  public DTDValueDef getValueDef()
  {
    return m_valueDef;
  }

  //--------------------------------------------------------------------
  public void setStringValue (String value)
  {
    if (value == null)
      value = new String();

    switch (m_valueDef.getDataType())
    {
      case DTDValueDef.DT_CDATA:

        try
        {
          parseType (m_valueDef.getValueTypeName(), value);
        }
        catch (IllegalArgumentException e)
        {
          m_typeClass = String.class;
          m_value = new String();
        }

        break;

      case DTDValueDef.DT_ENUMERATED:

        m_value = (m_valueDef.getEnumValues().indexOf (value) >= 0) ? value : new String();
        break;
    }
  }

  //--------------------------------------------------------------------
  public String getStringValue()
  {
    return m_value.toString();
  }

  //--------------------------------------------------------------------
  private void parseType (String typeName, String initValue) throws IllegalArgumentException
  {
    if (typeName.equals ("StringField"))
    {
      m_typeClass = String.class;
      m_editorClass = null;
      m_value = initValue;
      return;
    }

    if (typeName.equals ("ExtendedStringField"))
    {
      m_typeClass = String.class;

      if (m_editor == null)
        m_editor = new ExtendedStringEditor (m_valueDef.getFullName());

      m_value = initValue;
      return;
    }

    if (typeName.equals ("DirectoryField"))
    {
      m_typeClass = String.class;
      m_editorClass = ExtendedFolderNameEditor.class;
      m_value = initValue;
      return;
    }

    if (typeName.equals ("IntField"))
    {
      m_typeClass = Integer.class;
      m_editorClass = null;

      try
      {
        m_value = new Integer (initValue);
      }
      catch (NumberFormatException e)
      {
        m_value = new Integer (0);
      }      
      
      return;
    }

    if (typeName.equals ("BooleanField"))
    {
      m_typeClass = Boolean.class;
      m_editorClass = null;
      m_value = new Boolean (initValue.equals ("true"));
      return;
    }
    
    if (typeName.equals ("PasswordField"))
    {
      m_typeClass = String.class;
      m_editorClass = SwingPasswordEditor.class;
      m_value = initValue;
      return;
    }

    if (typeName.equals ("FileField"))
    {
      m_typeClass = String.class;
      m_editorClass = ExtendedFileNameEditor.class;
      m_value = initValue;
      return;
    }
    
    if (typeName.equals ("FloatField"))
    {
      m_typeClass = Float.class;
      m_editorClass = null;

      try
      {
        m_value = new Float (initValue);
      }
      catch (NumberFormatException e)
      {
        m_value = new Float (0);
      }
      
      return;
    }
    
    String errMsg = "Wrong valueType '" + typeName + "' in DTD-config file";

    Informator informator = new DefaultInformatorImpl();
    informator.printError (errMsg);

    throw new IllegalArgumentException (errMsg);
  }

  //--------------------------------------------------------------------
  public PropertyEditor getEditor()
  {
    PropertyEditor editor = null;

    switch (m_valueDef.getDataType())
    {
      case DTDValueDef.DT_CDATA:

        if (m_editor != null)
        {
          editor = m_editor;
          break;
        }

        if (m_editorClass != null)
        {
          try
          {
            editor = (PropertyEditor) m_editorClass.newInstance();
          }
          catch (Exception e) { }
        }

        break;

      case DTDValueDef.DT_ENUMERATED:

        Vector v = m_valueDef.getEnumValues();
        if (m_valueDef.getDefaultModifier() == DTDValueDef.DM_IMPLIED)
          v.insertElementAt ("<None>", 0);

        editor = new SwingComboBoxEditor (new DefaultComboBoxModel (v));
        break;
    }

    return editor;
  }

  //--------------------------------------------------------------------
  public Class getTypeClass()
  {
    return m_typeClass;
  }

  //--------------------------------------------------------------------
  public Object getValueObject()
  {
    return m_value;
  }

  //--------------------------------------------------------------------
  public void setValueObject (Object newValue)
  {
    if (m_valueDef.getDataType() == DTDValueDef.DT_ENUMERATED &&
        m_valueDef.getEnumValues().indexOf (newValue) < 0)
    {
      newValue = new String();
    }

    if (! newValue.equals (m_value))
    {
      m_value = newValue;
      m_xmlTreeManager.setModified (true);
    }
  }

  //--------------------------------------------------------------------
  /**
    name to be used in XML-editor to display value name;
    noted with (*) if model element's property will be updated upon this value
  */
	public String getDisplayName()
	{
		String result = m_valueDef.getFullName();

		if (getRwiPropertyToUpdate() != null)
		{
			result = result + " (*)";
		}

	 	return result;
	}

  //--------------------------------------------------------------------
	abstract protected String getRwiPropertyToUpdate();

  //--------------------------------------------------------------------
  public boolean hasReadonlyValue()
  {
    return m_valueDef.getDefaultModifier() == DTDValueDef.DM_FIXED;
  }
}
