package railo.runtime.tag;
import java.io.IOException;
import railo.commons.digest.MD5;
import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContextImpl;
import railo.runtime.PageSource;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.functions.image.ImageNew;
import railo.runtime.functions.image.ImageWrite;
import railo.runtime.img.Image;
import railo.runtime.op.Caster;
import railo.runtime.type.util.ListUtil;
public final class Sprite extends TagImpl {
private String _id;
private String _ids;
private String _srcs;
String src;
@Override
public void release() {
this._id=null;
this._ids=null;
this.src=null;
this._srcs=null;
super.release();
}
public void set_ids(String _ids){
this._ids=_ids;
}
public void set_id(String _id){
this._id=_id;
}
public void set_srcs(String _srcs){
this._srcs=_srcs;
}
public void setSrc(String src){
this.src=src;
}
@Override
public int doStartTag() throws PageException {
try {
return _doStartTag();
} catch (Throwable e) {
throw Caster.toPageException(e);
}
}
public int _doStartTag() throws Throwable {
// write out div for single item
pageContext.write("<div id=\""+_id+"\"></div>");
// handle all items
if(!StringUtil.isEmpty(_ids)) {
String[] ids=ListUtil.listToStringArray(_ids, ',');
String[] strSrcs=ListUtil.listToStringArray(_srcs, ',');
Resource[] srcs=new Resource[strSrcs.length];
Image[] images=new Image[strSrcs.length];
for(int i=0;i<srcs.length;i++){
srcs[i]=ResourceUtil.toResourceExisting(pageContext, strSrcs[i]);
images[i] = new Image(srcs[i]);
}
// TODO use the same resource as for cfimage
PageSource ps = pageContext.getCurrentTemplatePageSource();
Resource curr = ps.getResource();
Resource dir = curr.getParentResource();
Resource cssDir = dir.getRealResource("css");
Resource pathdir = cssDir;
cssDir.mkdirs();
//the base name for the files we are going to create as a css and image
String baseRenderedFileName = MD5.getDigestAsString(_ids);
Resource cssFileName = cssDir.getRealResource(baseRenderedFileName+".css");
Resource imgFileName = pathdir.getRealResource(baseRenderedFileName+"."+ResourceUtil.getExtension(src,""));
//if the files don't exist, then we create them, otherwise
boolean bCreate = !cssFileName.isFile() || !imgFileName.isFile();
//Are we going to create it, let's say no
String css = "";
if(bCreate){
int imgMaxHeight = 0;
int imgMaxWidth = 0;
Image img;
int actualWidth,actualHeight;
//Setup the max height and width of the new image.
for(int i=0;i<srcs.length;i++){
img = images[i];
//set the image original height and width
actualWidth = img.getWidth();;
actualHeight = img.getHeight();
//Check if there is a height,
imgMaxHeight += actualHeight;
if(actualWidth > imgMaxWidth) imgMaxWidth = actualWidth;
}
//Create the new image (hence we needed to do two of these items)
Image spriteImage = (Image) ImageNew.call(pageContext,"", ""+imgMaxWidth,""+imgMaxHeight, "argb");
int placedHeight = 0;
//Loop again but this time, lets do the copy and paste
for(int i=0;i<srcs.length;i++){
img = images[i];
spriteImage.paste(img,1,placedHeight);
css += "#"+ids[i]+" {\n\tbackground: url("+baseRenderedFileName+"."+ResourceUtil.getExtension(strSrcs[i],"")+") 0px -"+placedHeight+"px no-repeat; width:"+img.getWidth()+"px; height:"+img.getHeight()+"px;\n} \n";
placedHeight += img.getHeight();
}
//Now Write the CSS and the Sprite Image
ImageWrite.call(pageContext, spriteImage, imgFileName.getAbsolutePath());
IOUtil.write(cssFileName, css,"UTF-8",false);
}
//pageContext.write("<style>"+css+"</style>");
try {
((PageContextImpl)pageContext).getRootOut()
.appendHTMLHead("<link rel=\"stylesheet\" href=\"css/"+baseRenderedFileName+".css\" type=\"text/css\" media=\"screen\" title=\"no title\" charset=\"utf-8\">");
} catch (IOException e) {
Caster.toPageException(e);
}
}
return SKIP_BODY;
}
@Override
public int doEndTag() {
return EVAL_PAGE;
}
}