/*
 * Copyright 2000-2009 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.compiler;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.AbstractLayout;
import com.intellij.uiDesigner.core.Util;
import com.intellij.uiDesigner.lw.*;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

/**
 * @author yole
 */
public class GridBagConverter {
  private final Insets myInsets;
  private int myHGap;
  private int myVGap;
  private boolean mySameSizeHorz;
  private boolean mySameSizeVert;
  private final ArrayList myComponents = new ArrayList();
  private final ArrayList myConstraints = new ArrayList();
  private int myLastRow = -1;
  private int myLastCol = -1;

  public GridBagConverter() {
    myInsets = new Insets(0, 0, 0, 0);
  }

  public GridBagConverter(final Insets insets, final int hgap, final int vgap, final boolean sameSizeHorz, final boolean sameSizeVert) {
    myInsets = insets;
    myHGap = hgap;
    myVGap = vgap;
    mySameSizeHorz = sameSizeHorz;
    mySameSizeVert = sameSizeVert;
  }

  public void addComponent(final JComponent component, final GridConstraints constraints) {
    myComponents.add(component);
    myConstraints.add(constraints);
  }

  public static void prepareConstraints(final LwContainer container, final Map idToConstraintsMap) {
    GridLayoutManager gridLayout = (GridLayoutManager) container.getLayout();
    GridBagConverter converter = new GridBagConverter(gridLayout.getMargin(),
                                                      getGap(container, true),
                                                      getGap(container, false),
                                                      gridLayout.isSameSizeHorizontally(),
                                                      gridLayout.isSameSizeVertically());
    for(int i=0; i<container.getComponentCount(); i++) {
      final LwComponent component = (LwComponent)container.getComponent(i);
      if (component instanceof LwHSpacer || component instanceof LwVSpacer) {
        GridConstraints constraints = component.getConstraints().store();
        constraints.setHSizePolicy(constraints.getHSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
        constraints.setVSizePolicy(constraints.getVSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
        converter.addComponent(null, constraints);
      }
      else {
        converter.addComponent(null, component.getConstraints());
      }
    }
    Result[] results = converter.convert();
    int componentIndex = 0;
    for(int i=0; i<results.length; i++) {
      if (!results [i].isFillerPanel) {
        final LwComponent component = (LwComponent)container.getComponent(componentIndex++);
        idToConstraintsMap.put(component.getId(), results [i]);
      }
      // else generateFillerPanel(generator, componentLocal, results [i]);
    }
  }

  private static int getGap(LwContainer container, final boolean horizontal) {
    while(container != null) {
      final LayoutManager layout = container.getLayout();
      if (layout instanceof AbstractLayout) {
        AbstractLayout aLayout = (AbstractLayout) layout;
        final int gap = horizontal ? aLayout.getHGap() : aLayout.getVGap();
        if (gap >= 0) {
          return gap;
        }
      }
      container = container.getParent();
    }
    return horizontal ? AbstractLayout.DEFAULT_HGAP : AbstractLayout.DEFAULT_VGAP;
  }

  public static class Result {
    public JComponent component;
    public boolean isFillerPanel;
    public GridBagConstraints constraints;
    public Dimension preferredSize;
    public Dimension minimumSize;
    public Dimension maximumSize;

    public Result(final JComponent component) {
      this.component = component;
      constraints = new GridBagConstraints();
    }
  }

  public Result[] convert() {
    ArrayList results = new ArrayList();
    for(int i=0; i<myComponents.size(); i++) {
      results.add(convert((JComponent) myComponents.get(i), (GridConstraints) myConstraints.get(i)));
    }
    //addFillerPanels(results);
    final Result[] resultArray = (Result[])results.toArray(new Result[results.size()]);
    if (myHGap > 0 || myVGap > 0) {
      applyGaps(resultArray);
    }
    if (mySameSizeHorz) {
      makeSameSizes(resultArray, true);
    }
    if (mySameSizeVert) {
      makeSameSizes(resultArray, false);
    }

    return resultArray;
  }

  private void applyGaps(final Result[] resultArray) {
    int leftGap = myHGap/2;
    int rightGap = myHGap - myHGap/2;
    int topGap = myVGap / 2;
    int bottomGap = myVGap - myVGap/2;
    for(int i=0; i<resultArray.length; i++) {
      Result result = resultArray [i];
      if (result.constraints.gridx > 0) {
        result.constraints.insets.left += leftGap;
      }
      if (result.constraints.gridx + result.constraints.gridwidth-1 < myLastCol) {
        result.constraints.insets.right += rightGap;
      }
      if (result.constraints.gridy > 0) {
        result.constraints.insets.top += topGap;
      }
      if (result.constraints.gridy + result.constraints.gridheight-1 < myLastRow) {
        result.constraints.insets.bottom += bottomGap;
      }
    }
  }

  private static void makeSameSizes(final Result[] resultArray, boolean horizontal) {
    int minimum = -1;
    int preferred = -1;
    for(int i=0; i<resultArray.length; i++) {
      Result result = resultArray [i];
      Dimension minSize = result.minimumSize != null || result.component == null
                          ? result.minimumSize
                          : result.component.getMinimumSize();
      Dimension prefSize = result.preferredSize != null || result.component == null
                           ? result.preferredSize
                           : result.component.getPreferredSize();
      if (minSize != null) {
        minimum = Math.max(minimum, horizontal ? minSize.width : minSize.height);
      }
      if (prefSize != null) {
        preferred = Math.max(preferred, horizontal ? prefSize.width : prefSize.height);
      }
    }

    if (minimum >= 0 || preferred >= 0) {
      for(int i=0; i<resultArray.length; i++) {
        Result result = resultArray [i];

        if ((result.minimumSize != null || result.component != null) && minimum >= 0) {
          if (result.minimumSize == null) {
            result.minimumSize = result.component.getMinimumSize();
          }
          if (horizontal) {
            result.minimumSize.width = minimum;
          }
          else {
            result.minimumSize.height = minimum;
          }
        }

        if ((result.preferredSize != null || result.component != null) && preferred >= 0) {
          if (result.preferredSize == null) {
            result.preferredSize = result.component.getPreferredSize();
          }
          if (horizontal) {
            result.preferredSize.width = preferred;
          }
          else {
            result.preferredSize.height = preferred;
          }
        }
      }
    }
  }

  private Result convert(final JComponent component, final GridConstraints constraints) {
    final Result result = new Result(component);

    int endRow = constraints.getRow() + constraints.getRowSpan()-1;
    myLastRow = Math.max(myLastRow, endRow);
    int endCol = constraints.getColumn() + constraints.getColSpan()-1;
    myLastCol = Math.max(myLastCol, endCol);

    int indent = Util.DEFAULT_INDENT * constraints.getIndent();

    constraintsToGridBag(constraints, result.constraints);
    result.constraints.weightx = getWeight(constraints, true);
    result.constraints.weighty = getWeight(constraints, false);
    result.constraints.insets = new Insets(myInsets.top, myInsets.left + indent, myInsets.bottom, myInsets.right);

    Dimension minSize = constraints.myMinimumSize;
    if (component != null && minSize.width <= 0 && minSize.height <= 0) {
      minSize = component.getMinimumSize();
    }

    if ((constraints.getHSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
      minSize.width = constraints.myPreferredSize.width > 0 || component == null
                      ? constraints.myPreferredSize.width
                      : component.getPreferredSize().width;
    }
    if ((constraints.getVSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
      minSize.height = constraints.myPreferredSize.height > 0 || component == null
                       ? constraints.myPreferredSize.height
                       : component.getPreferredSize().height;
    }

    if (minSize.width != -1 || minSize.height != -1) {
      result.minimumSize = minSize;
    }

    if (constraints.myPreferredSize.width > 0 && constraints.myPreferredSize.height > 0) {
      result.preferredSize = constraints.myPreferredSize;
    }
    if (constraints.myMaximumSize.width > 0 && constraints.myMaximumSize.height > 0) {
      result.maximumSize = constraints.myMaximumSize;
    }

    return result;
  }

  public static GridBagConstraints getGridBagConstraints(IComponent component) {
    final GridBagConstraints gbc;
    if (component.getCustomLayoutConstraints() instanceof GridBagConstraints) {
      gbc = (GridBagConstraints) component.getCustomLayoutConstraints();
    }
    else {
      gbc = new GridBagConstraints();
    }
    constraintsToGridBag(component.getConstraints(), gbc);
    return gbc;
  }

  public static void constraintsToGridBag(final GridConstraints constraints, final GridBagConstraints result) {
    result.gridx = constraints.getColumn();
    result.gridy = constraints.getRow();
    result.gridwidth = constraints.getColSpan();
    result.gridheight = constraints.getRowSpan();
    switch(constraints.getFill()) {
      case GridConstraints.FILL_HORIZONTAL: result.fill = GridBagConstraints.HORIZONTAL; break;
      case GridConstraints.FILL_VERTICAL:   result.fill = GridBagConstraints.VERTICAL; break;
      case GridConstraints.FILL_BOTH:       result.fill = GridBagConstraints.BOTH; break;
      default:                              result.fill = GridBagConstraints.NONE; break;
    }
    switch(constraints.getAnchor()) {
      case GridConstraints.ANCHOR_NORTHWEST: result.anchor = GridBagConstraints.NORTHWEST; break;
      case GridConstraints.ANCHOR_NORTH:     result.anchor = GridBagConstraints.NORTH; break;
      case GridConstraints.ANCHOR_NORTHEAST: result.anchor = GridBagConstraints.NORTHEAST; break;
      case GridConstraints.ANCHOR_EAST:      result.anchor = GridBagConstraints.EAST; break;
      case GridConstraints.ANCHOR_SOUTHEAST: result.anchor = GridBagConstraints.SOUTHEAST; break;
      case GridConstraints.ANCHOR_SOUTH:     result.anchor = GridBagConstraints.SOUTH; break;
      case GridConstraints.ANCHOR_SOUTHWEST: result.anchor = GridBagConstraints.SOUTHWEST; break;
      case GridConstraints.ANCHOR_WEST:      result.anchor = GridBagConstraints.WEST; break;
    }
  }

  private double getWeight(final GridConstraints constraints, final boolean horizontal) {
    int policy = horizontal ? constraints.getHSizePolicy() : constraints.getVSizePolicy();
    if ((policy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
      return 1.0;
    }
    boolean canGrow = ((policy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0);
    for (Iterator iterator = myConstraints.iterator(); iterator.hasNext();) {
      GridConstraints otherConstraints = (GridConstraints)iterator.next();

      if (!constraintsIntersect(horizontal, constraints, otherConstraints)) {
        int otherPolicy = horizontal ? otherConstraints.getHSizePolicy() : otherConstraints.getVSizePolicy();
        if ((otherPolicy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
          return 0.0;
        }
        if (!canGrow && ((otherPolicy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0)) {
          return 0.0;
        }
      }
    }
    return 1.0;
  }

  private boolean constraintsIntersect(final boolean horizontal,
                                       final GridConstraints constraints,
                                       final GridConstraints otherConstraints) {
    int start = constraints.getCell(!horizontal);
    int end = start + constraints.getSpan(!horizontal) - 1;
    int otherStart = otherConstraints.getCell(!horizontal);
    int otherEnd = otherStart + otherConstraints.getSpan(!horizontal) - 1;
    return start <= otherEnd && otherStart <= end;
  }
}
