/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.intellij.uiDesigner.radComponents;

import com.intellij.ui.MappingListCellRenderer;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.util.containers.ContainerUtil;
import com.jgoodies.forms.layout.*;
import org.jetbrains.annotations.NonNls;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yole
 */
public class FormLayoutColumnProperties implements CustomPropertiesPanel {
  private static final Map<Object, String> UNITS_MAP;

  static {
    UNITS_MAP = new HashMap<Object, String>();
    UNITS_MAP.put("px", UIDesignerBundle.message("unit.pixels"));
    UNITS_MAP.put("dlu", UIDesignerBundle.message("unit.dialog.units"));
    UNITS_MAP.put("pt", UIDesignerBundle.message("unit.points"));
    UNITS_MAP.put("in", UIDesignerBundle.message("unit.inches"));
    UNITS_MAP.put("cm", UIDesignerBundle.message("unit.centimeters"));
    UNITS_MAP.put("mm", UIDesignerBundle.message("unit.millimeters"));
  }

  private JPanel myRootPanel;
  private JRadioButton myDefaultRadioButton;
  private JRadioButton myPreferredRadioButton;
  private JRadioButton myMinimumRadioButton;
  private JRadioButton myConstantRadioButton;
  private JComboBox myConstantSizeUnitsCombo;
  private JCheckBox myMinimumCheckBox;
  private JCheckBox myMaximumCheckBox;
  private JSpinner myMaxSizeSpinner;
  private JComboBox myMinSizeUnitsCombo;
  private JComboBox myMaxSizeUnitsCombo;
  private JSpinner myConstantSizeSpinner;
  private JSpinner myMinSizeSpinner;
  private JCheckBox myGrowCheckBox;
  private JSpinner myGrowSpinner;
  private JRadioButton myLeftRadioButton;
  private JRadioButton myCenterRadioButton;
  private JRadioButton myRightRadioButton;
  private JRadioButton myFillRadioButton;
  private JLabel myTitleLabel;
  private JPanel myAlignmentPanel;
  private JPanel mySizePanel;
  private FormLayout myLayout;
  private int myIndex;
  private boolean myIsRow;
  private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
  private boolean myShowing = false;
  private boolean mySaving = false;

  public FormLayoutColumnProperties() {
    @NonNls String[] unitNames = new String[]{"px", "dlu", "pt", "in", "cm", "mm"};
    myConstantSizeUnitsCombo.setModel(new DefaultComboBoxModel(unitNames));
    myMinSizeUnitsCombo.setModel(new DefaultComboBoxModel(unitNames));
    myMaxSizeUnitsCombo.setModel(new DefaultComboBoxModel(unitNames));
    myConstantSizeUnitsCombo.setRenderer(new MappingListCellRenderer(myConstantSizeUnitsCombo.getRenderer(), UNITS_MAP));
    myMinSizeUnitsCombo.setRenderer(new MappingListCellRenderer(myMinSizeUnitsCombo.getRenderer(), UNITS_MAP));
    myMaxSizeUnitsCombo.setRenderer(new MappingListCellRenderer(myMaxSizeUnitsCombo.getRenderer(), UNITS_MAP));
    final MyRadioListener listener = new MyRadioListener();
    myDefaultRadioButton.addActionListener(listener);
    myPreferredRadioButton.addActionListener(listener);
    myMinimumRadioButton.addActionListener(listener);
    myConstantRadioButton.addActionListener(listener);

    myMinimumCheckBox.addChangeListener(new MyCheckboxListener(myMinimumCheckBox, myMinSizeUnitsCombo, myMinSizeSpinner));
    myMaximumCheckBox.addChangeListener(new MyCheckboxListener(myMaximumCheckBox, myMaxSizeUnitsCombo, myMaxSizeSpinner));
    myConstantRadioButton.addChangeListener(new MyCheckboxListener(myConstantRadioButton, myConstantSizeUnitsCombo, myConstantSizeSpinner));

    updateOnRadioChange();

    myGrowCheckBox.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        myGrowSpinner.setEnabled(myGrowCheckBox.isSelected());
        updateSpec();
      }
    });
    final MyChangeListener changeListener = new MyChangeListener();
    myGrowSpinner.setModel(new SpinnerNumberModel(1.0, 0.0, 10.0, 0.1));
    myGrowSpinner.addChangeListener(changeListener);
    myMinSizeSpinner.addChangeListener(changeListener);
    myMaxSizeSpinner.addChangeListener(changeListener);
    myConstantSizeSpinner.addChangeListener(changeListener);
    myLeftRadioButton.addChangeListener(changeListener);
    myCenterRadioButton.addChangeListener(changeListener);
    myRightRadioButton.addChangeListener(changeListener);
    myFillRadioButton.addChangeListener(changeListener);

    final MyItemListener itemListener = new MyItemListener();
    myMinSizeUnitsCombo.addItemListener(itemListener);
    myMaxSizeUnitsCombo.addItemListener(itemListener);
    myConstantSizeUnitsCombo.addItemListener(itemListener);
  }

  public JPanel getComponent() {
    return myRootPanel;
  }

  public void addChangeListener(ChangeListener listener) {
    myListeners.add(listener);
  }

  public void removeChangeListener(ChangeListener listener) {
    myListeners.remove(listener);
  }

  public void showProperties(final RadContainer container, final boolean row, final int[] selectedIndices) {
    if (mySaving) return;
    if (selectedIndices.length == 1) {
      showControls(true);
      myShowing = true;
      try {
        myLayout = (FormLayout)container.getLayout();
        myIndex = selectedIndices[0] + 1;
        myIsRow = row;

        myTitleLabel.setText(myIsRow
                             ? UIDesignerBundle.message("title.row.properties", myIndex)
                             : UIDesignerBundle.message("title.column.properties", myIndex));
        myLeftRadioButton.setText(row ? UIDesignerBundle.message("alignment.top") : UIDesignerBundle.message("alignment.left"));
        myRightRadioButton.setText(row ? UIDesignerBundle.message("alignment.bottom") : UIDesignerBundle.message("alignment.right"));
        mySizePanel.setBorder(IdeBorderFactory.createTitledBorder(myIsRow
                                                                  ? UIDesignerBundle.message("title.height")
                                                                  : UIDesignerBundle.message("title.width"), true));

        FormSpec formSpec = row ? myLayout.getRowSpec(myIndex) : myLayout.getColumnSpec(myIndex);
        showAlignment(formSpec.getDefaultAlignment());
        showSize(formSpec.getSize());
        if (formSpec.getResizeWeight() < 0.01) {
          myGrowCheckBox.setSelected(false);
          myGrowSpinner.setValue(1.0);
        }
        else {
          myGrowCheckBox.setSelected(true);
          myGrowSpinner.setValue(formSpec.getResizeWeight());
        }
      }
      finally {
        myShowing = false;
      }
    }
    else {
      showControls(false);
      if (selectedIndices.length > 1) {
        myTitleLabel.setText(myIsRow
                             ? UIDesignerBundle.message("title.multiple.rows.selected")
                             : UIDesignerBundle.message("title.multiple.columns.selected"));
      }
      else {
        myTitleLabel.setText(myIsRow
                             ? UIDesignerBundle.message("title.no.rows.selected")
                             : UIDesignerBundle.message("title.no.columns.selected"));
      }
    }
  }

  private void showControls(final boolean visible) {
    mySizePanel.setVisible(visible);
    myAlignmentPanel.setVisible(visible);
    myGrowCheckBox.setVisible(visible);
    myGrowSpinner.setVisible(visible);
  }

  private void showAlignment(final FormSpec.DefaultAlignment defaultAlignment) {
    if (defaultAlignment.equals(RowSpec.TOP) || defaultAlignment.equals(ColumnSpec.LEFT)) {
      myLeftRadioButton.setSelected(true);
    }
    else if (defaultAlignment.equals(RowSpec.CENTER)) {
      myCenterRadioButton.setSelected(true);
    }
    else if (defaultAlignment.equals(RowSpec.BOTTOM) || defaultAlignment.equals(ColumnSpec.RIGHT)) {
      myRightRadioButton.setSelected(true);
    }
    else {
      myFillRadioButton.setSelected(true);
    }
  }

  private void showSize(Size size) {
    Size minimumSize = null;
    Size maximumSize = null;
    if (size instanceof BoundedSize) {
      BoundedSize boundedSize = (BoundedSize)size;
      minimumSize = boundedSize.getLowerBound();
      maximumSize = boundedSize.getUpperBound();
      size = boundedSize.getBasis();
    }

    if (size instanceof ConstantSize) {
      myConstantRadioButton.setSelected(true);
      myMinimumCheckBox.setEnabled(false);
      myMinimumCheckBox.setSelected(false);
      myMaximumCheckBox.setEnabled(false);
      myMaximumCheckBox.setSelected(false);
      showConstantSize((ConstantSize)size, myConstantSizeUnitsCombo, myConstantSizeSpinner);
    }
    else {
      @NonNls String s = size.toString();
      if (s.startsWith("m")) {
        myMinimumRadioButton.setSelected(true);
      }
      else if (s.startsWith("p")) {
        myPreferredRadioButton.setSelected(true);
      }
      else {
        myDefaultRadioButton.setSelected(true);
      }

      myMinimumCheckBox.setEnabled(true);
      myMaximumCheckBox.setEnabled(true);
      if (minimumSize instanceof ConstantSize) {
        myMinimumCheckBox.setSelected(true);
        myMaximumCheckBox.setEnabled(false);       // TODO: remove this code when IDEADEV-9678 is implemented
        showConstantSize((ConstantSize)minimumSize, myMinSizeUnitsCombo, myMinSizeSpinner);
      }
      else {
        myMinimumCheckBox.setSelected(false);
      }
      if (maximumSize instanceof ConstantSize) {
        myMaximumCheckBox.setSelected(true);
        myMinimumCheckBox.setEnabled(false);       // TODO: remove this code when IDEADEV-9678 is implemented 
        showConstantSize((ConstantSize)maximumSize, myMaxSizeUnitsCombo, myMaxSizeSpinner);
      }
      else {
        myMaximumCheckBox.setSelected(false);
      }
    }
  }

  private static void showConstantSize(final ConstantSize size, final JComboBox unitsCombo, final JSpinner spinner) {
    double value = size.getValue();
    ConstantSize.Unit unit = size.getUnit();
    if (unit.equals(ConstantSize.DIALOG_UNITS_X) || unit.equals(ConstantSize.DIALOG_UNITS_Y)) {
      unitsCombo.setSelectedItem("dlu");
    }
    else {
      unitsCombo.setSelectedItem(unit.abbreviation());
    }

    spinner.setModel(new SpinnerNumberModel(0.0, 0.0, Double.MAX_VALUE, 1.0));
    spinner.setValue(value);
  }

  private void updateOnRadioChange() {
    final boolean canSetBounds = !myConstantRadioButton.isSelected();
    myMinimumCheckBox.setEnabled(canSetBounds);
    myMaximumCheckBox.setEnabled(canSetBounds);

    // TODO: remove this code when IDEADEV-9678 is implemented
    if (myMinimumCheckBox.isSelected()) {
      myMaximumCheckBox.setEnabled(false);
      myMaximumCheckBox.setSelected(false);
    }
    else if (myMaximumCheckBox.isSelected()) {
      myMinimumCheckBox.setEnabled(false);
    }

    if (!canSetBounds) {
      myMinimumCheckBox.setSelected(false);
      myMaximumCheckBox.setSelected(false);
    }
    updateSpec();
  }

  private void updateSpec() {
    if (myLayout == null || myShowing) return;
    mySaving = true;
    try {
      Size size = getSelectedSize();

      final SpinnerNumberModel model = (SpinnerNumberModel)myGrowSpinner.getModel();
      double resizeWeight = myGrowCheckBox.isSelected() ? model.getNumber().doubleValue() : 0.0;
      FormSpec.DefaultAlignment alignment = getSelectedAlignment();

      if (myIsRow) {
        myLayout.setRowSpec(myIndex, new RowSpec(alignment, size, resizeWeight));
      }
      else {
        myLayout.setColumnSpec(myIndex, new ColumnSpec(alignment, size, resizeWeight));
      }
      for (ChangeListener listener : myListeners) {
        listener.stateChanged(new ChangeEvent(this));
      }
    }
    finally {
      mySaving = false;
    }
  }

  private Size getSelectedSize() {
    Size size;
    if (myDefaultRadioButton.isSelected()) {
      size = Sizes.DEFAULT;
    }
    else if (myPreferredRadioButton.isSelected()) {
      size = Sizes.PREFERRED;
    }
    else if (myMinimumRadioButton.isSelected()) {
      size = Sizes.MINIMUM;
    }
    else {
      size = getConstantSize(myConstantSizeUnitsCombo, myConstantSizeSpinner);
    }

    if (myMinimumCheckBox.isSelected() || myMaximumCheckBox.isSelected()) {
      Size minSize = null;
      Size maxSize = null;
      if (myMinimumCheckBox.isSelected()) {
        minSize = getConstantSize(myMinSizeUnitsCombo, myMinSizeSpinner);
      }
      if (myMaximumCheckBox.isSelected()) {
        maxSize = getConstantSize(myMaxSizeUnitsCombo, myMaxSizeSpinner);
      }
      size = Sizes.bounded(size, minSize, maxSize);
    }
    return size;
  }

  private FormSpec.DefaultAlignment getSelectedAlignment() {
    if (myLeftRadioButton.isSelected()) {
      return myIsRow ? RowSpec.TOP : ColumnSpec.LEFT;
    }
    if (myCenterRadioButton.isSelected()) {
      return RowSpec.CENTER;
    }
    if (myRightRadioButton.isSelected()) {
      return myIsRow ? RowSpec.BOTTOM : ColumnSpec.RIGHT;
    }
    return RowSpec.FILL;
  }

  private ConstantSize getConstantSize(final JComboBox unitsCombo, final JSpinner spinner) {
    return Sizes.constant(spinner.getValue().toString() + unitsCombo.getSelectedItem().toString(), myIsRow);
  }

  private class MyRadioListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      updateOnRadioChange();
    }
  }

  private class MyCheckboxListener implements ChangeListener {
    private boolean myWasSelected;
    private final AbstractButton myButton;
    private final JComboBox myUnitsCombo;
    private final JSpinner mySpinner;

    public MyCheckboxListener(final AbstractButton button, final JComboBox unitsCombo, final JSpinner spinner) {
      myButton = button;
      myUnitsCombo = unitsCombo;
      mySpinner = spinner;
      myWasSelected = myButton.isSelected();
    }

    public void stateChanged(ChangeEvent e) {
      if (myWasSelected != myButton.isSelected()) {
        myWasSelected = myButton.isSelected();
        myUnitsCombo.setEnabled(myButton.isSelected());
        mySpinner.setEnabled(myButton.isSelected());
        if (myButton.isSelected() && mySpinner.getValue().equals(new Integer(0))) {
          mySpinner.setValue(100);
        }
        updateOnRadioChange();
      }
    }
  }

  private class MyChangeListener implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
      updateSpec();
    }
  }

  private class MyItemListener implements ItemListener {
    public void itemStateChanged(ItemEvent e) {
      updateSpec();
    }
  }
}
