/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   $Project: polymake $$Id: EmbeddedGeometries.java,v 1.3 2004/08/27 09:41:01 thilosch Exp $
*/

package de.tuberlin.polymake.common;

import jv.geom.*;
import jv.vecmath.*;
import jv.object.*;
import jv.project.*;

import java.awt.*;
import java.util.*;

/**
 * This class implements ???
 * 
 * @author Thilo Schr&ouml;der
 */
public class EmbeddedGeometries {
    
    protected HashMap geomIndexMap = new HashMap(8);

    protected EmbeddedGeometry[] geometries;
    protected PgPointSet embedding = new PgPointSet();

    protected String name = "NoName";

    public EmbeddedGeometries(String title, EmbeddedGeometry[] geoms) {
	name = title;
	geometries = new EmbeddedGeometry[geoms.length];
	for(int i = 0; i < geometries.length; ++i) {
	    geometries[i] = (EmbeddedGeometry)geoms[i].clone();
	    geomIndexMap.put(geometries[i].getName(),new Integer(i));
	}
    }

    public EmbeddedGeometries(String title, PgPointSet emb, EmbeddedGeometry[] geoms) {
	name = title;
	if(emb != null) {
	    embedding = (PgPointSet)emb.clone();
	}
	embedding.setName(title);
	geometries = new EmbeddedGeometry[geoms.length];
	for(int i = 0; i < geometries.length; ++i) {
	    geometries[i] = (EmbeddedGeometry)geoms[i].clone();
	    geomIndexMap.put(geometries[i].getName(),new Integer(i));
	}
    }

    public void moveVertex(String geomName,int index, PdVector coords) {
	int geomIndex = ((Integer)geomIndexMap.get(geomName)).intValue();
	int vertexIndex = geometries[geomIndex].getVertexIndex(index);
	embedding.setVertex(vertexIndex,coords);
    }

    public PdVector getEmbeddedVertex(String geomName, int index) {
	int geomIndex = ((Integer)geomIndexMap.get(geomName)).intValue();
	int vertexIndex = geometries[geomIndex].getVertexIndex(index);
	PdVector tmpVertex = embedding.getVertex(vertexIndex);
	tmpVertex.setName(Integer.toString(vertexIndex));
	return tmpVertex;
    }

    public void update(PgPointSet ps, boolean clearTag) {
	name = ps.getName();
	embedding.setName(name);
	Color[] colors = embedding.getVertexColors();
	PdVector[] coords = ps.getVertices();
	if(embedding.getNumVertices() <= coords.length) {
	    embedding.setNumVertices(coords.length);
	}
	for(int i = 0; i < coords.length; ++i) {
	    double[] xyz = coords[i].getEntries();
	    if(coords[i].getName() != null) {
		embedding.setVertex(Integer.parseInt(coords[i].getName()),xyz[0],xyz[1],xyz[2]);
	    } else {
		embedding.setVertex(i,xyz[0],xyz[1],xyz[2]);
	    }
	}
	embedding.setVertexColors(colors);
	embedding.update(embedding);
	for(int i = 0; i < geometries.length; ++i) {
	    if(geometries[i].isDynamic()) {
		geometries[i].update(embedding,clearTag);
	    }
	}
    }

    public void update(PgPointSet ps) {
	update(ps, false);
    }

    public double[] getVertexCoords(int index) {
	return embedding.getVertex(index).getEntries();
    }

    public int getNumberOfGeometries() {
	return geometries.length;
    }
    
    public PgPointSet getEmbedding() {
	return (PgPointSet)embedding.clone();
    }

    public void setGeometry(int index, PgGeometry g) {
	geometries[index].setGeometry((PgGeometry)(g.clone()));
    }

    public PgGeometry getGeometry(int index) {
	return geometries[index].getGeometry();
    }

    public PgGeometry[] getGeometries() {
	PgGeometry[] polygonSets = new PgGeometry[geometries.length];
	for(int i = 0; i < polygonSets.length; ++i) {
	    polygonSets[i] = geometries[i].getGeometry();
	}
	return polygonSets;
    }

    public Vector getMarkedVertices() {
	Vector markedVertices = new Vector();
	for(int j=0; j < embedding.getNumVertices(); ++j) {
	    embedding.clearTagVertex(j,PsObject.IS_SELECTED);
	}
	for(int j = 0; j < geometries.length; ++j) {
	    PgPointSet m_geom = (PgPointSet)getGeometry(j);
	    for (int i = 0; i < m_geom.getNumVertices(); i++) {
		if (m_geom.hasTagVertex(i, PsObject.IS_SELECTED)) {
		    markedVertices.add(Integer.toString(geometries[j].vertexList[i]));
		    double[] vertex = m_geom.getVertex(i).getEntries();
		    embedding.setVertex(geometries[j].vertexList[i],vertex[0],vertex[1],vertex[2]);
		    embedding.setTagVertex(geometries[j].vertexList[i],PsObject.IS_SELECTED);
		}
	    }
	}
	return markedVertices;
    }

    public Color[] getVertexColors() {
	return embedding.getVertexColors();
    }
    
    public String getName() {
	return name;
    }
    
    public void setName(String name) {
	this.name = name;
    }

    public Object clone() {
	return new EmbeddedGeometries(name,embedding,geometries);
    }

    public String toString() {
	String msg = new String();
	msg += "name = " + name + "\n";
	msg += "embedding = " + embedding.toString() + "\n";
	for(int i = 0; i < geometries.length; ++i) {
	    msg += "geometries["+i+"]=" + geometries[i].toString();
	}
	return msg;
    }
}
