String renderPanel(String id, String title, String content) {
	String sOut = "";
  	
  	sOut += "<div id=\"div" + id + "\" class=\"panel\">\n";
  	sOut += "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"185\">\n";
  	sOut += "<tr>\n";
  	sOut += "	<td colspan=\"3\" width=\"185\" class=\"InfoPaneHeader\" id=\"td" + id + "\" onclick=\"toggleVisibility('div" + id + "'); return false;\">" + title + "</td>\n";
  	sOut += "</tr>\n";
  	sOut += "<tr>\n";
  	sOut += "	<td width=\"1\" class=\"InfoPaneFrame\"><img src=\"" + resPath + "/1x1.gif\" width=\"1\" height=\"1\"/></td>\n";
  	sOut += "	<td width=\"183\" class=\"InfoPaneRow\">" + content + "</td>\n";
  	sOut += "	<td width=\"1\" class=\"InfoPaneFrame\"><img src=\"" + resPath + "/1x1.gif\" width=\"1\" height=\"1\"/></td>\n";
  	sOut += "</tr>\n";
  	sOut += "<tr>\n";
  	sOut += "	<td width=\"185\" colspan=\"3\" class=\"InfoPaneFrame\"><img src=\"" + resPath + "/1x1.gif\" width=\"1\" height=\"1\"/></td>\n";
  	sOut += "</tr>\n";
  	sOut += "</table>\n";
  	sOut += "</div>\n";
  	
  	return sOut;
}
 
String renderPanelRow(String content, String cssPrefix) {
	String sOut = "";
  	
  	sOut += "<tr>\n";
  	sOut += "	<td width=\"1\" class=\"" + cssPrefix + "PaneFrame\"><img src=\"" + resPath + "/1x1.gif\" width=\"1\" height=\"1\"/></td>\n";
  	sOut += "	<td width=\"183\" class=\"" + cssPrefix + "PaneRow\">" + content + "</td>\n";
  	sOut += "	<td width=\"1\" class=\"" + cssPrefix + "PaneFrame\"><img src=\"" + resPath + "/1x1.gif\" width=\"1\" height=\"1\"/></td>\n";
  	sOut += "</tr>\n";
  	
  	return sOut;
}
 
String renderFoldState(String id) {
  	String sOut = "";
  	
	sOut += "	switch (readCookie('div" + id + "Overflow')) {\n";
	sOut += "		case '': return; \n";
	sOut += "		case 'hidden': \n";
	sOut += "			xHeight('div" + id + "', 23);\n";
	sOut += "			xGetElementById('div" + id + "').style.overflow = 'hidden';\n";
	sOut += "			xGetElementById('td" + id + "').setAttribute(\"class\", \"InfoPaneHeaderClosed\");\n";
	sOut += "			xGetElementById('td" + id + "').setAttribute(\"className\", \"InfoPaneHeaderClosed\");\n";
	sOut += "			break;\n";
	sOut += "		case 'visible':\n";
	sOut += "			xGetElementById('div" + id + "').style.height = '';\n";
	sOut += "			xGetElementById('div" + id + "').style.overflow = 'visible';\n";
	sOut += "			xGetElementById('td" + id + "').setAttribute(\"class\", \"InfoPaneHeader\");\n";
	sOut += "			xGetElementById('td" + id + "').setAttribute(\"className\", \"InfoPaneHeader\");\n";
	sOut += "			break;\n";
	sOut += "	}\n";
	
	return sOut;
}
  
File[] getIndexTemplates(File pluginDir) {
	// This filter only returns true if the File isn't a directory,
	// has a file ending of *.htt and starts with "index_".
	FileFilter fileFilter = new FileFilter() {
   		public boolean accept(File file) {
			return file.isFile() && file.getName().endsWith(".htt") && file.getName().startsWith("index_");
		}
	};
	
	return pluginDir.listFiles(fileFilter);
}
  
File[] getSlideTemplates(File pluginDir) {
	// This filter only returns true if the File isn't a directory,
	// has a file ending of *.htt and starts with "slide_".
	FileFilter fileFilter = new FileFilter() {
   		public boolean accept(File file) {
			return file.isFile() && file.getName().endsWith(".htt") && file.getName().startsWith("slide_");
		}
	};
	
	return pluginDir.listFiles(fileFilter);
}
  
File[] getOnceTemplates(File pluginDir) {
	// This filter only returns true if the File isn't a directory,
	// has a file ending of *.htt and starts with "once_".
	FileFilter fileFilter = new FileFilter() {
   		public boolean accept(File file) {
			return file.isFile() && file.getName().endsWith(".htt") && file.getName().startsWith("once_");
		}
	};
	
	return pluginDir.listFiles(fileFilter);
}

String getText(String key) {
	try {
		return album.get("texts").getObject(key);
	} catch (Exception ex) {
		return key;
	}
}

String getOnLoadJavascript(String plugin, boolean isIndex) {
	String sOut = "";
	
	File fJS = new File(skinDirectory, "plugins/" + plugin + "/javascriptOnLoad.htt");
	if (fJS.exists()) {
		sOut += engine.processTemplate(IO.readTextFile(fJS));
	}
	if (isIndex) {
		fJS = new File(skinDirectory, "plugins/" + plugin + "/javascriptOnLoadIndex.htt");
		if (fJS.exists())
			sOut += engine.processTemplate(IO.readTextFile(fJS));
	} else {
		fJS = new File(skinDirectory, "plugins/" + plugin + "/javascriptOnLoadSlide.htt");
		if (fJS.exists())
			sOut += engine.processTemplate(IO.readTextFile(fJS));
	}
	
	return sOut;
}

SmartResourceBundle getResources(String plugin) {
	// Read localized strings for plug-in
	SmartResourceBundle pluginTexts = null;
	Locale locale = null;
	try {
		locale = new Locale(language);
	} catch (Exception ex) {
		locale = Locale.getDefault();
	}
	File fPluginTexts = new File(skinDirectory, "plugins/" + plugin + "/texts");
	try {
		pluginTexts = SmartResourceBundle.getBundle(fPluginTexts, "texts", locale);
	} catch (Exception ex) {
	}
	album.put("texts", pluginTexts);

	return pluginTexts;
}
