/*
* File : Shaper.java
* Created : 10-may-2001 16:26
* By : fbusquets
*
* JClic - Authoring and playing system for educational activities
*
* Copyright (C) 2000 - 2005 Francesc Busquets & Departament
* d'Educacio de la Generalitat de Catalunya
*
* 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 of the License, or
* (at your option) any later version.
*
* 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 (see the LICENSE file).
*/
package edu.xtec.jclic.shapers;
import edu.xtec.jclic.boxes.BoxBase;
import edu.xtec.util.Domable;
import edu.xtec.util.JDomUtility;
import edu.xtec.util.Options;
import edu.xtec.util.TripleString;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Francesc Busquets (fbusquets@xtec.cat)
* @version 13.09.10
*/
public abstract class Shaper extends Object implements Cloneable, Domable {
protected final double WIDTH=1, HEIGHT=1;
protected static final String DELIM="|";
protected int nCols, nRows, nCells;
protected ShapeData[] shapeData;
protected boolean initiated=false;
/** Creates new Shaper */
public Shaper(int nx, int ny) {
reset(nx, ny);
}
public void reset(int nCols, int nRows){
this.nCols=nCols;
this.nRows=nRows;
nCells=nRows * nCols;
initiated=false;
shapeData=new ShapeData[nCells];
for(int i=0; i<nCells; i++)
shapeData[i]=new ShapeData();
}
public void reset(){
reset(nCols, nRows);
}
public static final String ELEMENT_NAME="shaper";
public static final String COLS="cols", ROWS="rows";
public static final String BASE_CLASS="edu.xtec.jclic.shapers.", BASE_CLASS_TAG="@";
public org.jdom.Element getJDomElement(){
org.jdom.Element e=new org.jdom.Element(ELEMENT_NAME);
e.setAttribute(JDomUtility.CLASS, getClassName());
e.setAttribute(COLS, Integer.toString(nCols));
e.setAttribute(ROWS, Integer.toString(nRows));
return e;
}
public String getClassName(){
String result=getClass().getName();
if(result.startsWith(BASE_CLASS))
result=BASE_CLASS_TAG+result.substring(BASE_CLASS.length());
return result;
}
public static Shaper getShaper(org.jdom.Element e) throws Exception{
JDomUtility.checkName(e, ELEMENT_NAME);
String className=JDomUtility.getClassName(e);
int cw=JDomUtility.getIntAttr(e, COLS, 1);
int ch=JDomUtility.getIntAttr(e, ROWS, 1);
Shaper sh=createShaper(className, cw, ch);
sh.setProperties(e, null);
return sh;
}
public static Shaper createShaper(String className, int cw, int ch) throws Exception{
if(className.startsWith(BASE_CLASS_TAG))
className=BASE_CLASS+className.substring(1);
Class<?> shaperClass;
java.lang.reflect.Constructor con;
Class[] cparams={int.class, int.class};
Object[] initArgs={new Integer(cw), new Integer(ch)};
shaperClass=Class.forName(className);
con=shaperClass.getConstructor(cparams);
return (Shaper)con.newInstance(initArgs);
}
//public void copyPropertiesFrom(Shaper sh){}
protected abstract void buildShapes();
public boolean rectangularShapes(){
return false;
}
public String getEditorPanelClassName(){
return null;
}
public Shaper edit(Component parent, Options options, Dimension dim, Image img, BoxBase bb){
Shaper result=null;
if(getEditorPanelClassName()!=null){
try{
Class<?> cl=Class.forName(getEditorPanelClassName());
java.lang.reflect.Method m=cl.getMethod("getShaper", new Class[]{
Shaper.class, Component.class, Options.class, Dimension.class, Image.class, BoxBase.class
});
result=(Shaper)m.invoke(null, new Object[]{this, parent, options, dim, img, bb});
} catch(Exception ex){
options.getMessages().showErrorWarning(parent, "edit_act_shaper_err", ex);
}
}
return result;
}
public void setProperties(org.jdom.Element e, Object aux) throws Exception{
}
public Shape getShape(int n, Rectangle2D rect){
if(!initiated)
buildShapes();
if(n>=nCells || shapeData[n]==null)
return null;
return shapeData[n].getShape(rect);
}
public ShapeData getShapeData(int n){
return (n>=0 && n<shapeData.length) ? shapeData[n] : null;
}
protected ShapeData getEnclosingShapeData(){
ShapeData sh=new ShapeData();
sh.moveTo(0, 0);
sh.lineTo(1.0, 0);
sh.lineTo(1.0, 1.0);
sh.lineTo(0, 1.0);
sh.closePath();
return sh;
}
public boolean hasRemainder(){
return false;
}
public Shape getRemainderShape(Rectangle2D rect){
if(!hasRemainder())
return null;
if(!initiated)
buildShapes();
GeneralPath gp=(GeneralPath)(getEnclosingShapeData().getShape(rect));
gp.setWindingRule(GeneralPath.WIND_EVEN_ODD);
for(int i=0; i<nCells; i++){
if(shapeData[i]!=null)
gp.append(shapeData[i].getShape(rect), false);
}
return gp;
}
public int getNumRows(){
return nRows;
}
public void setNumRows(int n){
if(n>0 && n!=nRows)
reset(nCols, n);
}
public int getNumColumns(){
return nCols;
}
public void setNumColumns(int n){
if(n>0 && n!=nCols)
reset(nRows, n);
}
public int getNumCells(){
return nCells;
}
public static final String SYSTEM_LIST="shapers.listshapers";
public static List getSystemShaperList(Options options){
List<TripleString> result=new ArrayList<TripleString>();
try{
result=TripleString.getTripleList(SYSTEM_LIST, options, false, true, true);
} catch(Exception ex){
System.err.println("Error reading list of shapers!\n"+ex);
}
return result;
}
@Override
public Object clone() throws CloneNotSupportedException {
Shaper clon=(Shaper)super.clone();
clon.shapeData=(ShapeData[])shapeData.clone();
for(int i=0; i<shapeData.length; i++){
if(shapeData[i]!=null)
clon.shapeData[i]=(ShapeData)shapeData[i].clone();
}
return clon;
}
}