/*
* File : ActiveBoxContent.java
* Created : 02-may-2001 15:29
* 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.boxes;
import edu.xtec.jclic.Constants;
import edu.xtec.jclic.PlayStation;
import edu.xtec.jclic.bags.MediaBag;
import edu.xtec.jclic.bags.MediaBagElement;
import edu.xtec.jclic.fileSystem.FileSystem;
import edu.xtec.jclic.media.ActiveMediaPlayer;
import edu.xtec.jclic.media.MediaContent;
import edu.xtec.util.Domable;
import edu.xtec.util.JDomUtility;
import edu.xtec.util.ResourceManager;
import edu.xtec.util.StrUtils;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.Map;
/**
* This class defines a content that can be displayed by {@link edu.xtec.jclic.boxes.ActiveBox}
* objects. This content can be a text, an image, a fragment of an image or a
* combination of text and images. The style (colours, font and size, etc.) can be specified
* in a {@link edu.xtec.jclic.boxes.BoxBase} object. It stores also information about
* the optimal size and location of the <CODE>ActiveBox</CODE>.
* @author Francesc Busquets (fbusquets@xtec.cat)
* @version 13.09.09
*/
public class ActiveBoxContent extends Object implements Cloneable, Domable{
public BoxBase bb=null;
public Dimension dimension=null;
public Boolean border=null;
public String text=null;
public String imgName=null;
public Shape imgClip=null;
public MediaContent mediaContent=null;
public int[] imgAlign=new int[]{JDomUtility.ALIGN_MIDDLE,JDomUtility.ALIGN_MIDDLE};
public int[] txtAlign=new int[]{JDomUtility.ALIGN_MIDDLE,JDomUtility.ALIGN_MIDDLE};
public boolean avoidOverlapping=false;
public int id=-1;
public int item=-1;
public Image img=null;
// static fields
protected static ActiveBoxContent EMPTY_CONTENT;
// transient properties
public Object userData=null;
public String rawText=null;
public String htmlText=null;
public String innerHtmlText=null;
public boolean animated=false;
public ActiveMediaPlayer amp=null;
protected void copyRawDataFrom(ActiveBoxContent src){
bb=src.bb;
dimension=src.dimension;
border=src.border;
text=src.text;
imgName=src.imgName;
imgClip=src.imgClip;
mediaContent=src.mediaContent;
imgAlign=src.imgAlign;
txtAlign=src.txtAlign;
avoidOverlapping=src.avoidOverlapping;
id=src.id;
item=src.item;
img=src.img;
userData=src.userData;
rawText=src.rawText;
htmlText=src.htmlText;
innerHtmlText=src.innerHtmlText;
animated=src.animated;
amp=src.amp;
}
/** Creates new ActiveBoxContent */
public ActiveBoxContent() {
}
public static ActiveBoxContent getEmptyContent(){
if(EMPTY_CONTENT==null)
EMPTY_CONTENT=new ActiveBoxContent();
return EMPTY_CONTENT;
}
public static final String ELEMENT_NAME="cell";
protected static final String
ID="id", ITEM="item",
WIDTH="width", HEIGHT="height", BORDER="border",
IMAGE="image", TXTALIGN="txtAlign", IMGALIGN="imgAlign",
AVOID_OVERLAPPING="avoidOverlapping";
public org.jdom.Element getJDomElement(){
org.jdom.Element e=new org.jdom.Element(ELEMENT_NAME);
if(id!=-1)
e.setAttribute(ID, Integer.toString(id));
if(item!=-1)
e.setAttribute(ITEM, Integer.toString(item));
JDomUtility.setAlignProp(e, TXTALIGN, txtAlign, true);
JDomUtility.setAlignProp(e, IMGALIGN, imgAlign, true);
if(avoidOverlapping)
e.setAttribute(AVOID_OVERLAPPING, JDomUtility.boolString(avoidOverlapping));
if(dimension!=null){
e.setAttribute(WIDTH, Integer.toString(dimension.width));
e.setAttribute(HEIGHT, Integer.toString(dimension.height));
}
if(border!=null)
e.setAttribute(BORDER, JDomUtility.boolString(border.booleanValue()));
if(imgName!=null)
e.setAttribute(IMAGE, imgName);
if(bb!=null)
e.addContent(bb.getJDomElement());
if(mediaContent!=null)
e.addContent(mediaContent.getJDomElement());
if(text!=null)
JDomUtility.setParagraphs(e, text);
return e;
}
public static final int EMPTY_CELL=0, ONLY_ID=1, HAS_CONTENT=2;
public int testCellContents(){
if(JDomUtility.isDefaultAlign(txtAlign)
&& JDomUtility.isDefaultAlign(imgAlign)
&& !avoidOverlapping
&& dimension==null
&& border==null && imgName==null && bb==null && mediaContent==null
&& (text==null || text.length()==0)){
return ((id==-1 && item==-1) ? EMPTY_CELL : ONLY_ID);
}
return HAS_CONTENT;
}
public static ActiveBoxContent getActiveBoxContent(org.jdom.Element e, MediaBag mediaBag) throws Exception{
ActiveBoxContent abc=new ActiveBoxContent();
abc.setProperties(e, mediaBag);
return abc;
}
public void setProperties(org.jdom.Element e, Object aux) throws Exception{
JDomUtility.checkName(e, ELEMENT_NAME);
MediaBag mediaBag=(MediaBag)aux;
org.jdom.Element child;
id=JDomUtility.getIntAttr(e, ID, id);
item=JDomUtility.getIntAttr(e, ITEM, item);
if(e.getAttribute(JDomUtility.HALIGN)!=null || e.getAttribute(JDomUtility.VALIGN)!=null){
// old version!!!
txtAlign[0]=JDomUtility.getHAlign(e, txtAlign[0]);
txtAlign[1]=JDomUtility.getVAlign(e, txtAlign[1]);
imgAlign[0]=txtAlign[0];
imgAlign[1]=txtAlign[1];
}
else{
txtAlign=JDomUtility.getAlignProp(e, TXTALIGN, txtAlign);
imgAlign=JDomUtility.getAlignProp(e, IMGALIGN, imgAlign);
}
avoidOverlapping=JDomUtility.getBoolAttr(e, AVOID_OVERLAPPING, avoidOverlapping);
dimension=JDomUtility.getDimensionAttr(e, WIDTH, HEIGHT, dimension);
border=JDomUtility.getBooleanAttr(e, BORDER, border);
imgName=FileSystem.stdFn(e.getAttributeValue(IMAGE));
if((child=e.getChild(BoxBase.ELEMENT_NAME))!=null)
setBoxBase(BoxBase.getBoxBase(child));
if((child=e.getChild(MediaContent.ELEMENT_NAME))!=null)
mediaContent=MediaContent.getMediaContent(child);
setTextContent(JDomUtility.getParagraphs(e));
if(mediaBag!=null)
realizeContent(mediaBag);
}
public static void listReferences(org.jdom.Element e, Map<String,String> map){
if(e!=null){
String s=e.getAttributeValue(IMAGE);
if(s!=null && s.length()>0)
map.put(s, Constants.MEDIA_OBJECT);
org.jdom.Element child=e.getChild(MediaContent.ELEMENT_NAME);
if(child!=null)
MediaContent.listReferences(child, map);
}
}
@Override
public Object clone(){
ActiveBoxContent abc=null;
try{
abc=(ActiveBoxContent)super.clone();
abc.txtAlign=new int[]{txtAlign[0], txtAlign[1]};
abc.imgAlign=new int[]{imgAlign[0], imgAlign[1]};
} catch(Exception ex){
System.err.println("Unexpected error cloning ActiveBoxContent!");
}
return abc;
}
public void realizeContent(MediaBag mediaBag) throws Exception{
//todo: check global img and imgclip
//img=null;
//animated=false;
if(imgName!=null){
MediaBagElement mbe=mediaBag.getImageElement(imgName);
if(mbe!=null){
img=mbe.getImage();
animated=mbe.animated;
}
}
if(mediaContent!=null){
mediaContent.registerContentTo(mediaBag);
if(img==null && (text==null || text.length()==0)){
String s=mediaContent.getIconName();
img=ResourceManager.getImageIcon("icons/"+s).getImage();
}
}
checkHtmlText(mediaBag);
}
public boolean isEmpty(){
return (text==null && img==null);
}
public boolean isEquivalent(ActiveBoxContent abc, boolean checkCase){
if(abc==this) return true;
boolean result=false;
if(abc!=null){
if(isEmpty() && abc.isEmpty())
result=(id==abc.id);
else
result=(text==null
? abc.text==null
: (checkCase ? text.equals(abc.text) : text.equalsIgnoreCase(abc.text)))
&& (mediaContent==null
? abc.mediaContent==null
: mediaContent.isEquivalent(abc.mediaContent))
&& (img == abc.img)
&& (imgClip==null ? abc.imgClip==null : imgClip.equals(abc.imgClip));
}
return result;
}
@Override
public boolean equals(Object o){
boolean result=(o==this);
if(!result && o!=null && o instanceof ActiveBoxContent){
ActiveBoxContent abc=(ActiveBoxContent)o;
result = isEquivalent(abc, true)
&& ((bb==null && abc.bb==null) || (bb!=null && bb.equals(abc.bb)))
&& txtAlign[0]==abc.txtAlign[0] && txtAlign[1]==abc.txtAlign[1]
&& imgAlign[0]==abc.imgAlign[0] && imgAlign[1]==abc.imgAlign[1]
&& avoidOverlapping==abc.avoidOverlapping;
}
return result;
}
public void setTextContent(String tx){
// only plain text!
if(tx!=null){
rawText=tx;
text=tx;
checkHtmlText(null);
}
else{
rawText=null;
text=null;
htmlText=null;
innerHtmlText=null;
}
}
protected void checkHtmlText(MediaBag mediaBag){
htmlText=null;
innerHtmlText=null;
if(text!=null && text.substring(0).toLowerCase().startsWith("<html>")){
htmlText=text;
if(mediaBag!=null){
FileSystem fs=mediaBag.getProject().getFileSystem();
String path=fs.root;
if(!fs.isUrlBased())
path="file:"+FileSystem.sysFn(path);
htmlText=StrUtils.replace(htmlText, "SRC=\"", "SRC=\""+path);
htmlText=StrUtils.replace(htmlText, "src=\"", "src=\""+path);
}
String s=htmlText.substring(0).toLowerCase();
if(s.indexOf("<body")==-1){
int s2=s.indexOf("</html>");
if(s2>=0){
innerHtmlText=htmlText.substring(6, s2);
}
}
}
}
public void setImgContent(Image setImg, Shape setImgClip){
img=setImg;
imgName=null;
imgClip=setImgClip;
}
public void setImgAlign(int[] align){
imgAlign[0]=align[0];
imgAlign[1]=align[1];
}
public void setImgAlign(int h, int v){
imgAlign[0]=h;
imgAlign[1]=v;
}
public void setTxtAlign(int[] align){
txtAlign[0]=align[0];
txtAlign[1]=align[1];
}
public void setTxtAlign(int h, int v){
txtAlign[0]=h;
txtAlign[1]=v;
}
public void prepareMedia(PlayStation ps){
if(mediaContent!=null)
amp=ps.getActiveMediaPlayer(mediaContent);
else
amp=null;
}
public void setBoxBase(BoxBase boxBase){
bb=boxBase;
}
public void setDimension(Dimension d){
dimension=d;
}
public Dimension getDimension(){
return dimension;
}
public void setBorder(boolean b){
border=b;
}
public void copyStyleTo(ActiveBoxContent abc){
if(abc!=null){
abc.setBoxBase(bb);
if(border!=null)
abc.setBorder(border.booleanValue());
}
}
public String getDescription(){
StringBuilder result=new StringBuilder();
if(text!=null && text.length()>0) result.append(text);
else if(imgName!=null)
result.append("IMG:").append(imgName);
else if(imgClip!=null){
Rectangle r=imgClip.getBounds();
result.append("[").append(r.x).append(",").append(r.y).append(",");
result.append(r.width).append(",").append(r.height).append("]");
}
if(mediaContent!=null){
if(result.length()>0) result.append(' ');
result.append(mediaContent.getDescription());
}
return result.substring(0);
}
}