/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package shape;


import java.awt.*;
import java.util.*;
import java.awt.geom.*;
import DrawTop.*;
import geomExtension.*;
import shapeUtil.*;
import util.*;
import util.UndoConstants;

public class GroupElement extends ShapeElement{
     private ArrayList childrenList=new ArrayList();

     public static int debug=0;

     public GroupElement(){
         super();
     }

   public int getTypeE(){
        return Command.GROUP;
   }

    public String getShapeIdString(){
         return "Group";
    }

    public Shape getShape(){return null;}
    public boolean isClosed(){return false;}
    public Curve2D getCurve2D(){return null;}
    public void setCurve2D(Curve2D curve){}
    public SerializableCurve2D getSerializableCurve2D(){return null;}
    public void setSerializableCurve2D(SerializableCurve2D curve2Ddata){}

    public Rectangle2D getBoundingBox(){
         ShapeContainer[] shapeContainers=this.getGroupedSingleShapeContainers();
         Rectangle2D boundingBox=null;
         double xmin=Math.pow(10, 4), ymin=xmin, xmax=-xmin, ymax=-xmin;
         for(int i=0;i<shapeContainers.length;i++){
             boundingBox=shapeContainers[i].getBoundingBox();
             //boundingBox=((ShapeContainer)shapeContainers[i]).getBoundingBox();
             if(boundingBox==null){
                 System.err.println("*** Warning GroupElement "+
                         shapeContainers[i].getShapeId()+": boundingBox=null");
                 return null;
             }
             double x=boundingBox.getX();
             double y=boundingBox.getY();
             double w=boundingBox.getWidth();
             double h=boundingBox.getHeight();
             if(x<xmin) xmin=x;
             if(y<ymin) ymin=y;
             if(x+w>xmax) xmax=x+w;
             if(y+h>ymax) ymax=y+h;
         }
         Rectangle2D groupBoundingBox=
            new Rectangle2D.Double(xmin, ymin, xmax-xmin, ymax-ymin);
         return groupBoundingBox;
    }

    public Point2D[] getEndPTs(){
         Point2D[] PTs=new Point2D[0];
         return PTs;
    }
    
    public Rectangle2D createTextArea(){
        return null;
    }
    
    public Point2D[] getSamplingPTs(Rectangle2D box){return new Point2D[0];}
    public CurvePT[] getSamplingCurvePTs(Rectangle2D box){return null;}
//ShapeElement
    public SegmentModifier[] getSegmentModifiers(){
        SegmentModifier[] modifiers=new SegmentModifier[0];
        return modifiers;
    }
//ShapeElement
    public Point2D[] getModifierPTs(){
        Point2D[] PTs=new Point2D[0];
        return PTs;
    }
    
    //public void mouseStart(int ctrl, Point2D startPoint){}

    public void mouseStart(int ctrl, Point2D startPoint){
        super.mouseStart(ctrl, startPoint);
        this.getShapeContainer().setChangeCode(UndoConstants.SIZE_POSITION);
        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().mouseStart(ctrl, startPoint);
        }
    }

    public void create(Point2D startPoint, Point2D currentPoint){}
    public void create(Rectangle2D boundingBox){}
    public void create(Point2D[] points){}


    public void move(int ctrl, Point2D currentPoint, boolean resizeTextBox){
        Rectangle2D oldBox=this.getBoundingBox();
        double x=this.startBox.getX();
        double y=this.startBox.getY();
        double w=this.startBox.getWidth();
        double h=this.startBox.getHeight();
        double moveX=currentPoint.getX()-this.startPoint.getX();
        double moveY=currentPoint.getY()-this.startPoint.getY();
        Rectangle2D newBox=new Rectangle.Double(x+moveX, y+moveY, w, h);
        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().moveResize(oldBox, newBox, resizeTextBox);
        }
    }
/*
    public void move(int ctrl, Point2D currentPoint, boolean resizeTextBox){
        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().move(ctrl, currentPoint, resizeTextBox);
        }
    }
 */
    public void resize(int ctrl, Point2D currentPoint, String mousePosition, boolean resizeTextBox){
        Rectangle2D oldBox=this.getBoundingBox();
        boolean resizable=this.shapeContainer.getBooleanProperty("Enable_Resizing", "GroupElement");
        boolean keep_aspect_ratio=this.shapeContainer.getBooleanProperty("Keep_Aspect_Ratio", "GroupElement");
        if(!resizable) return;
        if(keep_aspect_ratio) ctrl=1;
        Rectangle2D newBox=ShapeElementUtil.resizeRectangle(ctrl, this.startBox, this.startPoint,
            currentPoint, mousePosition);

        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().moveResize(oldBox, newBox,resizeTextBox);
            //childShapeContainers[i].getElement().resize(ctrl, currentPoint, mousePositionCode,
            //        resizeTextBox);
        }
    }
/*
    public void resize(int ctrl, Point2D currentPoint, int mousePositionCode, boolean resizeTextBox){
        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().resize(ctrl, currentPoint, mousePositionCode,
                    resizeTextBox);
        }
    }
 */
    public void moveResize(Rectangle2D oldBox, Rectangle2D newBox, boolean resizeTextBox){
        this.getShapeContainer().setChangeCode(UndoConstants.SIZE_POSITION);
        ShapeContainer[] childShapeContainers=this.getGroupedSingleShapeContainers();
        int size=0;
        if(childShapeContainers!=null) size=childShapeContainers.length;
        for(int i=0;i<size;i++){
            childShapeContainers[i].getElement().moveResize(oldBox, newBox, true);
        }
    }

    public void moveEndPoint(int ctrl, int movePtIndex, Point2D currentPoint){};
    public void moveEndPoint(int ctrl, int movingIndex, Point2D oldPoint, Point2D newPoint){}
    public void modify(int ctrl, Point2D oldPoint, Point2D newPoint){}
    public void modifyPoint(Point2D point, String command){}
    //public int deletePoint(Point2D point){return 0;}


    public ArrayList getChildrenList(){
        return this.childrenList;
    }


    public void setChildrenList(ArrayList childrenList){
        this.childrenList=childrenList;
    }

    public ShapeContainer[] getChildren(){
         int size=0;
         if(childrenList!=null) size=childrenList.size();
         ShapeContainer[] containers=new ShapeContainer[size];
         for(int i=0;i<size;i++) containers[i]=(ShapeContainer)childrenList.get(i);
         return containers;
    }


    public void addChildren(ShapeContainer container) {
        int position=this.childrenList.indexOf(container);
        if(position>=0){
            this.childrenList.remove(position);
        } else {
            this.childrenList.add(container);
        }
    } 

    public ShapeContainer[] getGroupedContainers(){
        Vector vector=new Vector();
        this.getGroupedContainers(vector);
        int length=0;
        if(vector.size()>0) length=vector.size();
        ShapeContainer[] containers=new ShapeContainer[length];
        for(int i=0;i<length;i++){
            containers[i]=(ShapeContainer)vector.get(i);
        }
        return containers;
    }

    public void getGroupedContainers(Vector vector){
        ArrayList childrenList=this.childrenList;
        int size=0;
        if(this.childrenList!=null) size=childrenList.size();
        for(int i=0;i<size;i++){
            ShapeContainer container=(ShapeContainer)childrenList.get(i);
            int type=container.getContainerType();
            if(type==ShapeContainer.SHAPE) vector.add(container);
            else {
                ShapeContainer shapeContainer=(ShapeContainer)container;
                vector.add(shapeContainer);
                GroupElement groupElement=(GroupElement)shapeContainer.getElement();
                groupElement.getGroupedContainers(vector);
            }
        }
        return;
    }

    public ShapeContainer[] getGroupedSingleShapeContainers(){
        Vector vector=new Vector();
        this.getGroupedSingleShapeContainers(vector);
        int length=0;
        if(vector.size()>0) length=vector.size();
        ShapeContainer[] shapeContainers=new ShapeContainer[length];
        for(int i=0;i<length;i++){
            shapeContainers[i]=(ShapeContainer)vector.get(i);
        }
        return shapeContainers;
    }

    public void getGroupedSingleShapeContainers(Vector vector){
        ArrayList childrenList=this.childrenList;
        int size=0;
        if(this.childrenList!=null) size=childrenList.size();
        for(int i=0;i<size;i++){
            ShapeContainer container=(ShapeContainer)childrenList.get(i);
            int type=container.getContainerType();
            if(type==ShapeContainer.SHAPE) vector.add(container);
            else {
                ShapeContainer shapeContainer=(ShapeContainer)container;
                GroupElement groupElement=(GroupElement)shapeContainer.getElement();
                groupElement.getGroupedSingleShapeContainers(vector);
            }
        }
        return;
    }
	
	public void getGroupTreeDepth(Vector vector)  {
		Integer treeDepth=(Integer)vector.get(1);
		++treeDepth;
		if(debug>0) System.out.println("   ** GroupElement getGroupTreeDepth treeDepth="+treeDepth+
				", search shapeId="+(String)vector.get(0)
				+", target shapeId="+this.getShapeContainer().getShapeId());
		vector.set(1, treeDepth);
		ArrayList childrenList = this.childrenList;
		int size = 0;
		if (this.childrenList != null) {
			size = childrenList.size();
		}
		for (int i = 0; i < size; i++) {
			ShapeContainer childContainer = (ShapeContainer) childrenList.get(i);
			int type = childContainer.getContainerType();
			//if (type == ShapeContainer.SHAPE) {
				String shapeId=(String)vector.get(0);
				if(childContainer.getShapeId().equals(shapeId)){
					vector.set(2,(new Integer(treeDepth)));
					return;
				}
			if (type == ShapeContainer.GROUP) {
				GroupElement groupElement = (GroupElement)childContainer.getElement();
				groupElement.getGroupTreeDepth(vector);
			}
		}
		treeDepth=(Integer)vector.get(1);
		--treeDepth;
		vector.set(1, treeDepth);
		return;
	}
/*
	public int getGroupTreeDepth(String shapeId, int treeDepth) {
		++treeDepth;
		int depth=-1;
		ArrayList childrenList = this.childrenList;
		int size = 0;
		if (this.childrenList != null) {
			size = childrenList.size();
		}
		for (int i = 0; i < size; i++) {
			ShapeContainer childContainer = (ShapeContainer) childrenList.get(i);
			int type = childContainer.getContainerType();
			String cildShapeId = childContainer.getShapeId();
			if (shapeId.equals(cildShapeId)) {
				depth=treeDepth;
				--treeDepth;
				return depth;
			}
			if (type == ShapeContainer.GROUP) {
				//vector.add(shapeContainer);
				GroupElement groupElement = (GroupElement)childContainer.getElement();
				depth=groupElement.getGroupTreeDepth(shapeId, treeDepth);
				if(depth>=0){
					--treeDepth;
					return depth;
				}
			}
		}
		--treeDepth;
		return -1;
	}
*/
    public Object clone(){return null;}

    public String toString(){
        String str="";
        ShapeContainer[] children=this.getChildren();
        int size=0;
        if(children!=null) size=children.length;
        for(int i=0;i<size;i++) {
            if(children[i]==null) continue;
            str+=children[i].getShapeId()+", ";
        }
        str+="\n    ** all containers under this group --> ";
        ShapeContainer[] containers=this.getGroupedContainers();
        size=0;
        if(containers!=null) size=containers.length;
        for(int i=0;i<size;i++) {
            if(i>0) str+=", ";
            str+=containers[i].getShapeId();
        }
        return str;
    } 
        
    public String toShortString(){
        String str="";
        ShapeContainer[] containers=this.getChildren();
        int size=0;
        if(containers!=null) size=containers.length;
        for(int i=0;i<size;i++) {
            if(containers[i]==null) continue;
            if(i>0) str+=", ";
            str+=containers[i].getShapeId();
        }
        return str;
    } 

 } 