package org.timepedia.chronoscope.client.axis;

import org.timepedia.chronoscope.client.canvas.Bounds;
import org.timepedia.chronoscope.client.canvas.Layer;
import org.timepedia.chronoscope.client.canvas.View;
import org.timepedia.chronoscope.client.gss.GssElement;
import org.timepedia.chronoscope.client.gss.GssProperties;
import org.timepedia.chronoscope.client.plot.DefaultXYPlot;

import java.util.ArrayList;

/**
 * An AxisPanel is a container which holds multiple Axis objects <p/> In
 * addition to holding Axis objects, AxisPanels are positioned
 * (LEFT/RIGHT/TOP/BOTTOM) and have orientation. <p/> They are responsible for
 * partitioning their space and allocating that space to each Axis, as well as
 * using GSS "axes" properties to fill the background of the panel when
 * cleared.
 */
public class AxisPanel implements GssElement {

  public enum Position {
    LEFT {
      public boolean isLeftRight() { return true; };
      public boolean isTopBottom() { return !isLeftRight(); };
    }, 
    RIGHT {
      public boolean isLeftRight() { return true; };
      public boolean isTopBottom() { return !isLeftRight(); };
    },
    TOP {
      public boolean isLeftRight() { return false; };
      public boolean isTopBottom() { return !isLeftRight(); };
    },
    BOTTOM {
      public boolean isLeftRight() { return false; };
      public boolean isTopBottom() { return !isLeftRight(); };
    };
    
    /**
     * True only if this position is left or right.
     */
    public abstract boolean isLeftRight();
    
    /**
     * True only if this position is top or bottom.
     */
    public abstract boolean isTopBottom();
      
  }
  
  //public static final int LEFT = 0, RIGHT = 1, TOP = 2, BOTTOM = 3;

  public static final int VERTICAL_AXIS = 0;

  public static final int HORIZONTAL_AXIS = 1;

  private final ArrayList<ValueAxis> axes = new ArrayList<ValueAxis>();

  private boolean layerConfigured = false;

  private final String panelName;

  private final Position position;

  private GssProperties axesProperties;

  private int orientation;

  public AxisPanel(String panelName, Position position) {
    this.panelName = panelName;
    this.position = position;
    this.orientation = position.isLeftRight() ? VERTICAL_AXIS : HORIZONTAL_AXIS;
  }

  public void add(ValueAxis axis) {
    axes.add(axis);
    axis.init();
  }

  public boolean contains(ValueAxis theAxis) {
    return axes.contains(theAxis);
  }

  public void drawAxisPanel(DefaultXYPlot plot, Layer layer,
      Bounds panelPosition, boolean gridOnly) {

    if (axes.size() == 0) {
      return;
    }
    View view = plot.getChart().getView();

    if (axesProperties == null) {
      axesProperties = view.getGssProperties(this, "");
    }

    if (!gridOnly) {
      clearPanel(layer, panelPosition);
    }
    Bounds lPBounds = new Bounds(panelPosition);

    for (int i = 0; i < axes.size(); i++) {
      if (!layerConfigured) {
        layer.setTextLayerBounds(panelName + i, lPBounds);
      }
      ValueAxis axis = (ValueAxis) axes.get(i);
      lPBounds.width = axis.getWidth();
      lPBounds.height = axis.getHeight();

      axis.drawAxis(plot, layer, lPBounds, gridOnly);
      if (axis.getOrientation() == HORIZONTAL_AXIS) {
        lPBounds.y += lPBounds.height;
      } else {
        lPBounds.x += lPBounds.width;
      }
    }
    layerConfigured = true;
  }

  public int getAxisCount() {
    return axes.size();
  }

  public int getAxisNumber(ValueAxis axis) {
    return axes.indexOf(axis);
  }

  public double getHeight() {
    double height = 0;
    for (int i = 0; i < axes.size(); i++) {
      ValueAxis a = (ValueAxis) axes.get(i);
      if (a.getOrientation() == HORIZONTAL_AXIS) {
        height += a.getHeight();
      } else {
        height = a.getHeight();
      }
    }
    return height;
  }

  public int getOrientation() {
    return orientation;
  }

  public String getPanelName() {
    return panelName;
  }

  public GssElement getParentGssElement() {
    return null;
  }

  public Position getPosition() {
    return position;
  }

  public String getType() {
    return "axes";
  }

  public String getTypeClass() {
    switch (position) {
      case LEFT:
        return "left";
      case RIGHT:
        return "right";
      case TOP:
        return "top";
      case BOTTOM:
        return "bottom";
      default:
        return null;
    }
  }

  public double getWidth() {
    double width = 0;
    for (int i = 0; i < axes.size(); i++) {
      ValueAxis a = (ValueAxis) axes.get(i);
      if (a.getOrientation() == VERTICAL_AXIS) {
        width += a.getWidth();
      } else {
        width = Math.max(width, a.getWidth());
      }
    }
    return width;
  }

  public void remove(ValueAxis axis) {
    axes.remove(axis);
  }

  private void clearPanel(Layer layer, Bounds panelPosition) {
    layer.save();
    layer.setFillColor(this.axesProperties.bgColor);
    layer.setStrokeColor("#ffffff");
    if (position.isTopBottom()) {
      layer.scale(layer.getWidth(), layer.getHeight());
    } else if (panelPosition.area() > 0){
      layer.scale(panelPosition.width, panelPosition.height);
      layer.translate(panelPosition.x, panelPosition.y);
    }

//        layer.beginPath();
//        layer.setShadowBlur(0);
//        layer.setStrokeColor("rgba(0,0,0,0)");
//
//        layer.rect(0, 0, 1, 1);
//        layer.fill();
//        layer.stroke();
    layer.clearRect(0, 0, 1, 1);
    layer.restore();
    
  }
}

@@ -935,79 +935,16 @@
  %7D;%0A
-      public boolean isTopBottom() %7B return !isLeftRight(); %7D;%0A
     %7D, %0A
     
@@ -939,16 +939,16 @@
     %7D, %0A
+
     RIGH
@@ -1008,71 +1008,8 @@
  %7D;%0A
-      public boolean isTopBottom() %7B return !isLeftRight(); %7D;%0A
     
@@ -1079,71 +1079,8 @@
  %7D;%0A
-      public boolean isTopBottom() %7B return !isLeftRight(); %7D;%0A
     
@@ -1153,71 +1153,8 @@
  %7D;%0A
-      public boolean isTopBottom() %7B return !isLeftRight(); %7D;%0A
     
@@ -1352,33 +1352,24 @@
 %0A    public 
-abstract 
 boolean isTo
@@ -1377,17 +1377,53 @@
 Bottom()
-;
+ %7B%0A      return !isLeftRight();%0A    %7D
 %0A      %0A

In AxisPanel.Position enum, remove code duplication of isTopBottom() method