/*
   * This method apply the new value for the specified property
   * The oldValue can be wrong or null if a multiselection was performed
   * return true if the object is modified...
   */
  private boolean applyNewParameterProperty(
      JRParameter param, String propertyName, Object oldValue, Object newValue) {
    if (propertyName == null) return false;

    boolean objectModified = true;

    if (propertyName.equals("parameterName")) {
      SubDataset paramSubdataset = Misc.getObjectSubDataset(getJrf().getReport(), param);
      if (paramSubdataset != null && newValue != null) {
        for (int i = 0; i < paramSubdataset.getParameters().size(); ++i) {
          JRParameter f = (JRParameter) paramSubdataset.getParameters().get(i);
          if (f.getName().equals(newValue)) {
            ((SheetProperty) this.getSheetProperty(propertyName))
                .setLabelError(
                    I18n.getString(
                        "messages.jRParameterDialog.DuplicatedParameterName",
                        "A parameter with this name already exists!"));
            ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
            return false;
          }
        }

        param.setName("" + newValue);
        ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
        ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
      }
    } else if (propertyName.equals("parameterIsForPrompting")) {
      param.setIsForPrompting(((Boolean) newValue).booleanValue());
    } else if (propertyName.equals("parameterDescription")) {
      if (newValue != null) {
        param.setDescription("" + newValue);
      }
    } else if (propertyName.equals("parameterProperties")) {
      if (newValue != null && newValue instanceof List) {
        param.setProperties((List) newValue);
      }
    } else if (propertyName.equals("parameterClassType")) {
      if (newValue != null) {
        param.setClassType("" + newValue);
      }
    } else if (propertyName.equals("parameterDefaultValueExpression")) {
      if (newValue != null) {
        param.setDefaultValueExpression("" + newValue);
      }
      ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
      ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
    }

    return objectModified;
  }
  /*
   * This method apply the new value for the specified property
   * The oldValue can be wrong or null if a multiselection was performed
   * return true if the object is modified...
   */
  private boolean applyNewFieldProperty(
      JRField field, String propertyName, Object oldValue, Object newValue) {
    if (propertyName == null) return false;

    boolean objectModified = true;

    if (propertyName.equals("fieldName")) {
      SubDataset paramSubdataset = Misc.getObjectSubDataset(getJrf().getReport(), field);
      if (paramSubdataset != null && newValue != null) {
        for (int i = 0; i < paramSubdataset.getFields().size(); ++i) {
          JRField f = (JRField) paramSubdataset.getFields().get(i);
          if (f.getName().equals(newValue)) {
            ((SheetProperty) this.getSheetProperty(propertyName))
                .setLabelError(
                    I18n.getString(
                        "messages.JRFieldDialog.DuplicatedFieldName",
                        "A field with this name already exists!"));
            ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
            return false;
          }
        }

        field.setName("" + newValue);
        ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
        ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
      }
    } else if (propertyName.equals("fieldDescription")) {
      if (newValue != null) {
        field.setDescription("" + newValue);
      }
    } else if (propertyName.equals("fieldProperties")) {
      if (newValue != null && newValue instanceof List) {
        field.setProperties((List) newValue);
      }
    } else if (propertyName.equals("fieldClassType")) {
      if (newValue != null) {
        field.setClassType("" + newValue);
      }
    }

    return objectModified;
  }
  /*
   * This method apply the new value for the specified property
   * The oldValue can be wrong or null if a multiselection was performed
   * return true if the object is modified...
   */
  private boolean applyNewVariableProperty(
      JRVariable variable, String propertyName, Object oldValue, Object newValue) {
    if (propertyName == null) return false;

    boolean objectModified = true;

    if (propertyName.equals("variableName")) {
      SubDataset paramSubdataset = Misc.getObjectSubDataset(getJrf().getReport(), variable);
      if (paramSubdataset != null && newValue != null) {
        for (int i = 0; i < paramSubdataset.getVariables().size(); ++i) {
          JRVariable f = (JRVariable) paramSubdataset.getVariables().get(i);
          if (f.getName().equals(newValue)) {
            ((SheetProperty) this.getSheetProperty(propertyName))
                .setLabelError(
                    I18n.getString(
                        "messages.JRVariableDialog.DuplicatedVariableName",
                        "A variable with this name already exists!"));
            ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
            return false;
          }
        }

        variable.setName("" + newValue);
        ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
        ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
      }
    } else if (propertyName.equals("variableClassType")) {
      if (newValue != null) {
        variable.setClassType("" + newValue);
      }
    } else if (propertyName.equals("variableCalculationType")) {
      if (newValue != null) {
        variable.setCalculation("" + newValue);
      }
    } else if (propertyName.equals("variableResetType")) {
      if (newValue != null) {
        variable.setResetType("" + newValue);
      }
      if (newValue != null && newValue.equals("Group")) {
        spVariableResetGroup.setReadOnly(false);
        variable.setResetGroup(spVariableResetGroup.getValue() + "");
      } else {
        spVariableResetGroup.setReadOnly(true);
        variable.setResetGroup("");
      }
      spVariableResetGroup.updateLabel();
    } else if (propertyName.equals("variableResetGroup")) {
      variable.setResetGroup((newValue == null) ? "" : "" + newValue);
    } else if (propertyName.equals("variableIncrementType")) {
      if (newValue != null) {
        variable.setIncrementType("" + newValue);
      }
      if (newValue != null && newValue.equals("Group")) {
        spVariableIncrementGroup.setReadOnly(false);
        variable.setResetGroup(spVariableIncrementGroup.getValue() + "");
      } else {
        spVariableIncrementGroup.setReadOnly(true);
        variable.setIncrementGroup("");
      }
      spVariableIncrementGroup.updateLabel();
    } else if (propertyName.equals("variableIncrementGroup")) {
      variable.setIncrementGroup((newValue == null) ? "" : "" + newValue);
    } else if (propertyName.equals("variableIncrementerClass")) {
      variable.setIncrementerFactoryClass((newValue == null) ? "" : "" + newValue);
    } else if (propertyName.equals("variableExpression")) {
      if (newValue != null) {
        variable.setExpression("" + newValue);
      }
      ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
      ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
    } else if (propertyName.equals("variableInitialValueExpression")) {
      if (newValue != null) {
        variable.setInitialValueExpression("" + newValue);
      }
      ((SheetProperty) this.getSheetProperty(propertyName)).setLabelError(null);
      ((SheetProperty) this.getSheetProperty(propertyName)).updateLabel();
    }

    return objectModified;
  }
  /** This methos is called when a property changes... */
  public void sheetPropertyValueChanged(SheetPropertyValueChangedEvent evt) {
    if (isInit()) return;

    try {
      setInit(true);
      // System.out.println("Changed: " + evt.getPropertyName());
      // if (isNullItem((SheetProperty)evt.getSource())) return;

      // removeNullItem( (SheetProperty)evt.getSource() );

      Vector selectedElements = getSelection();

      Vector modified_parameters = new Vector();
      Vector original_parameters = new Vector();

      Vector modified_fields = new Vector();
      Vector original_fields = new Vector();

      Vector modified_variables = new Vector();
      Vector original_variables = new Vector();

      for (int i = 0; i < selectedElements.size(); ++i) {

        Object object = selectedElements.elementAt(i);

        if (object instanceof JRParameter) {
          JRParameter param = (JRParameter) object;
          if (param.isBuiltin()) continue;
          JRParameter originalParam = param.cloneMe();
          if (applyNewParameterProperty(
              param, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue())) {
            modified_parameters.add(object);
            original_parameters.add(originalParam);
          }
        } else if (object instanceof JRField) {
          JRField field = (JRField) object;
          JRField originalField = field.cloneMe();
          if (applyNewFieldProperty(
              field, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue())) {
            modified_fields.add(object);
            original_fields.add(originalField);
          }
        } else if (object instanceof JRVariable) {
          JRVariable variable = (JRVariable) object;
          JRVariable originalVariable = variable.cloneMe();
          if (applyNewVariableProperty(
              variable, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue())) {
            modified_variables.add(object);
            original_variables.add(originalVariable);
          }
        }

        // don't listen to these events...

        for (int k = 0; k < modified_parameters.size(); ++k) {
          JRParameter param = (JRParameter) modified_parameters.get(k);
          JRParameter oldParam = (JRParameter) original_parameters.get(k);
          SubDataset sd = Misc.getObjectSubDataset(getJrf().getReport(), param);
          sd.fireSubDatasetObjectChangedListenerSubDatasetObjectChanged(
              new it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent(
                  sd,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.PARAMETER,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.MODIFIED,
                  oldParam,
                  param));
        }

        for (int k = 0; k < modified_fields.size(); ++k) {
          JRField field = (JRField) modified_fields.get(k);
          JRField oldField = (JRField) original_fields.get(k);
          SubDataset sd = Misc.getObjectSubDataset(getJrf().getReport(), field);
          sd.fireSubDatasetObjectChangedListenerSubDatasetObjectChanged(
              new it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent(
                  sd,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.FIELD,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.MODIFIED,
                  oldField,
                  field));
        }

        for (int k = 0; k < modified_variables.size(); ++k) {
          JRVariable variable = (JRVariable) modified_variables.get(k);
          JRVariable oldVariable = (JRVariable) original_variables.get(k);
          SubDataset sd = Misc.getObjectSubDataset(getJrf().getReport(), variable);
          sd.fireSubDatasetObjectChangedListenerSubDatasetObjectChanged(
              new it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent(
                  sd,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.VARIABLE,
                  it.businesslogic.ireport.gui.event.SubDatasetObjectChangedEvent.MODIFIED,
                  oldVariable,
                  variable));
        }
      }

      getJrf().getReport().incrementReportChanges();

    } finally {
      setInit(false);
    }
  }
  /** Update all the element properties... */
  public void updateSelection(JReportFrame newJrf) {

    // Improving speed...
    // Do nothing if there are elements selected...
    if (newJrf != null && newJrf.getSelectedElements().size() > 0) return;

    // Fix for numbers focus losing...
    if (newJrf == null) {
      this.setSelection(new Vector());
    } else {
      this.setSelection(newJrf.getSelectedObjects());
    }

    setInit(true);

    this.removeAllProperties();

    this.jrf = newJrf;

    if (jrf == null || getSelection().size() == 0) {
      this.recreateSheet();
      return;
    }

    try {
      Vector selectedElements = getSelection();

      boolean sameParameterDescription = true;
      boolean sameParameterDefaultValueExpression = true;
      boolean sameParameterClassType = true;
      boolean sameParameterIsForPrompting = true;

      boolean sameFieldDescription = true;
      boolean sameFieldClassType = true;

      boolean sameVariableResetType = true;
      boolean sameVariableResetGroup = true;
      boolean sameVariableCalculationType = true;
      boolean sameVariableClassType = true;
      boolean sameVariableExpression = true;
      boolean sameVariableInitialValueExpression = true;
      boolean sameVariableIncrementGroup = true;
      boolean sameVariableIncrementType = true;
      boolean sameVariableIncrementerClass = true;

      boolean areAllparameters = true;
      boolean areAllfields = true;
      boolean areAllvariables = true;
      boolean isTheFirstElement = true;

      boolean areBuiltInParameters = false; // True if one ore more parameter is builtin...
      boolean areBuiltInVariables = false; // True if one ore more parameter is builtin...

      SubDataset subdataset = null;

      for (int i = 0; i < selectedElements.size(); ++i) {
        Object obj = selectedElements.elementAt(i);

        if (!(obj instanceof JRParameter)) {
          areAllparameters = false;
        }

        if (!(obj instanceof JRField)) {
          areAllfields = false;
        }

        if (!(obj instanceof JRVariable)) {
          areAllvariables = false;
        }

        if (isTheFirstElement) {
          subdataset = Misc.getObjectSubDataset(jrf.getReport(), obj);
          updateAllComboBoxes(subdataset);
        } else if (subdataset != null) {
          SubDataset s2 = Misc.getObjectSubDataset(subdataset, obj);
          if (s2 != subdataset) {
            subdataset = null;
          }
        }

        if (areAllparameters) {
          JRParameter param = (JRParameter) selectedElements.elementAt(i);

          if (!areBuiltInParameters) {
            areBuiltInParameters = param.isBuiltin();
          }

          if (selectedElements.size() == 1) {
            // Single parameter selectes...
            setTextArea(isTheFirstElement, param.getName(), spParameterName);
            spParameterProperties.setValue(param.getProperties());
          }
          if (sameParameterDescription)
            sameParameterDescription =
                setTextArea(isTheFirstElement, param.getDescription(), spParameterDescription);
          if (sameParameterDefaultValueExpression)
            sameParameterDefaultValueExpression =
                setTextArea(
                    isTheFirstElement,
                    param.getDefaultValueExpression(),
                    spParameterDefaultValueExpression);
          if (sameParameterClassType)
            sameParameterClassType =
                setGenericSheetProperty(
                    isTheFirstElement, param.getClassType(), spParameterClassType);
          if (sameParameterIsForPrompting)
            sameParameterIsForPrompting =
                this.setCheckBox(
                    isTheFirstElement, param.isIsForPrompting(), false, spParameterIsForPrompting);
        }

        if (areAllfields) {
          JRField field = (JRField) selectedElements.elementAt(i);

          if (selectedElements.size() == 1) {
            // Single parameter selectes...
            setTextArea(isTheFirstElement, field.getName(), spFieldName);
            spFieldProperties.setValue(field.getProperties());
          }
          if (sameFieldDescription)
            sameFieldDescription =
                setTextArea(isTheFirstElement, field.getDescription(), spFieldDescription);
          if (sameFieldClassType)
            sameFieldClassType =
                setGenericSheetProperty(isTheFirstElement, field.getClassType(), spFieldClassType);
        }

        if (areAllvariables) {
          JRVariable variable = (JRVariable) selectedElements.elementAt(i);

          if (!areBuiltInVariables) {
            areBuiltInVariables = variable.isBuiltin();
          }

          if (selectedElements.size() == 1) {
            // Single parameter selectes...
            setTextArea(isTheFirstElement, variable.getName(), spVariableName);
          }

          if (subdataset != null) {
            if (sameVariableResetType)
              sameVariableResetType =
                  setTagComboBox(isTheFirstElement, variable.getResetType(), spVariableResetType);
            if (sameVariableResetGroup)
              sameVariableResetGroup =
                  setTagComboBox(isTheFirstElement, variable.getResetGroup(), spVariableResetGroup);
            if (sameVariableIncrementType)
              sameVariableIncrementType =
                  setTagComboBox(
                      isTheFirstElement, variable.getIncrementType(), spVariableIncrementType);
            if (sameVariableIncrementGroup)
              sameVariableIncrementGroup =
                  setTagComboBox(
                      isTheFirstElement, variable.getIncrementGroup(), spVariableIncrementGroup);
          }

          if (sameVariableCalculationType)
            sameVariableCalculationType =
                setTagComboBox(
                    isTheFirstElement, variable.getCalculation(), spVariableCalculationType);
          if (sameVariableIncrementerClass)
            sameVariableIncrementerClass =
                setTextArea(
                    isTheFirstElement,
                    variable.getIncrementerFactoryClass(),
                    spVariableIncrementerClass);
          if (sameVariableClassType)
            sameVariableClassType =
                setGenericSheetProperty(
                    isTheFirstElement, variable.getClassType(), spVariableClassType);
          if (sameVariableExpression)
            sameVariableExpression =
                setTextArea(isTheFirstElement, variable.getExpression(), spVariableExpression);
          if (sameVariableInitialValueExpression)
            sameVariableInitialValueExpression =
                setTextArea(
                    isTheFirstElement,
                    variable.getInitialValueExpression(),
                    spVariableInitialValueExpression);
        }

        isTheFirstElement = false;
      }

      // TO DO: change this!

      // get the common subdataset...
      if (subdataset != null) {
        ExpressionContext ec = new ExpressionContext();
        ec.setSubDataset(subdataset);
        spParameterDefaultValueExpression.setExpressionContext(ec);
        spVariableExpression.setExpressionContext(ec);
        spVariableInitialValueExpression.setExpressionContext(ec);
      }

      spParameterDefaultValueExpression.setLabelError(null);
      spParameterDefaultValueExpression.updateLabel();

      spVariableExpression.setLabelError(null);
      spVariableExpression.updateLabel();

      spVariableInitialValueExpression.setLabelError(null);
      spVariableInitialValueExpression.updateLabel();

      if (areAllparameters) {

        String commonStr =
            it.businesslogic.ireport.util.I18n.getString(
                "parameterProperties", "Parameter Properties");
        if (getSelection().size() == 1) this.addSheetProperty(commonStr, spParameterName);
        spParameterIsForPrompting.setDefaultValue(new Boolean(true));
        this.addSheetProperty(commonStr, spParameterClassType);
        spParameterClassType.setLabelColor(
            (sameParameterClassType)
                ? mandatoryPropertiesLabelColor
                : sharedDifferentValueLabelColor);

        if (!areBuiltInParameters) {
          spParameterName.setReadOnly(false);
          spParameterClassType.setReadOnly(false);
          spParameterIsForPrompting.setLabelColor(
              (sameParameterIsForPrompting)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spParameterIsForPrompting);
          spParameterDefaultValueExpression.setLabelColor(
              (sameParameterDefaultValueExpression)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spParameterDefaultValueExpression);
          if (getSelection().size() == 1) this.addSheetProperty(commonStr, spParameterProperties);
        } else {
          spParameterName.setReadOnly(true);
          spParameterClassType.setReadOnly(true);
        }

      } else if (areAllfields) {
        String commonStr =
            it.businesslogic.ireport.util.I18n.getString("fieldProperties", "Field Properties");
        if (getSelection().size() == 1) this.addSheetProperty(commonStr, spFieldName);
        spFieldClassType.setLabelColor(
            (sameFieldClassType) ? mandatoryPropertiesLabelColor : sharedDifferentValueLabelColor);
        this.addSheetProperty(commonStr, spFieldClassType);
        spFieldDescription.setLabelColor(
            (sameFieldDescription)
                ? mandatoryPropertiesLabelColor
                : sharedDifferentValueLabelColor);
        this.addSheetProperty(commonStr, spFieldDescription);
        if (getSelection().size() == 1) this.addSheetProperty(commonStr, spFieldProperties);

      } else if (areAllvariables) {
        String commonStr =
            it.businesslogic.ireport.util.I18n.getString(
                "variableProperties", "Variable Properties");
        if (getSelection().size() == 1) this.addSheetProperty(commonStr, spVariableName);

        spVariableClassType.setLabelColor(
            (sameVariableClassType)
                ? mandatoryPropertiesLabelColor
                : sharedDifferentValueLabelColor);
        this.addSheetProperty(commonStr, spVariableClassType);

        if (!areBuiltInVariables) {
          spVariableName.setReadOnly(false);
          spVariableClassType.setReadOnly(false);

          spVariableCalculationType.setLabelColor(
              (sameVariableCalculationType)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spVariableCalculationType);

          if (subdataset != null) {
            spVariableResetType.setLabelColor(
                (sameVariableResetType)
                    ? mandatoryPropertiesLabelColor
                    : sharedDifferentValueLabelColor);
            this.addSheetProperty(commonStr, spVariableResetType);
            spVariableResetGroup.setLabelColor(
                (sameVariableResetGroup)
                    ? mandatoryPropertiesLabelColor
                    : sharedDifferentValueLabelColor);
            this.addSheetProperty(commonStr, spVariableResetGroup);
            spVariableIncrementType.setLabelColor(
                (sameVariableIncrementType)
                    ? mandatoryPropertiesLabelColor
                    : sharedDifferentValueLabelColor);
            this.addSheetProperty(commonStr, spVariableIncrementType);
            spVariableIncrementGroup.setLabelColor(
                (sameVariableIncrementGroup)
                    ? mandatoryPropertiesLabelColor
                    : sharedDifferentValueLabelColor);
            this.addSheetProperty(commonStr, spVariableIncrementGroup);

            if (!sameVariableResetType || !spVariableResetType.getValue().equals("Group")) {
              spVariableResetGroup.setReadOnly(true);
            } else {
              spVariableResetGroup.setReadOnly(false);
            }

            if (!sameVariableIncrementType || !spVariableIncrementType.getValue().equals("Group")) {
              spVariableIncrementGroup.setReadOnly(true);
            } else {
              spVariableIncrementGroup.setReadOnly(false);
            }
          }
          spVariableIncrementerClass.setLabelColor(
              (sameVariableIncrementerClass)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spVariableIncrementerClass);
          spVariableExpression.setLabelColor(
              (sameVariableExpression)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spVariableExpression);
          spVariableInitialValueExpression.setLabelColor(
              (sameVariableInitialValueExpression)
                  ? mandatoryPropertiesLabelColor
                  : sharedDifferentValueLabelColor);
          this.addSheetProperty(commonStr, spVariableInitialValueExpression);

        } else {
          spVariableName.setReadOnly(true);
          spVariableClassType.setReadOnly(true);
        }
      }

      this.recreateSheet();

    } catch (Exception ex) {
      ex.printStackTrace();
    } finally {

    }

    setInit(false);
  }