package com.diodesoftware.scb;
import org.apache.log4j.*;
import javax.servlet.jsp.tagext.TagSupport;
import javax.servlet.jsp.PageContext;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.io.IOException;
import java.sql.Date;
public class DateTimeTag
extends TagSupport
{
private String epoch;
private String yearField = epoch + "year";
private String monthField = epoch + "month";
private String dayField = epoch + "day";
private String hourField = epoch + "hourField";
private String minuteField = epoch + "minuteField";
private static final String GET_DATE_FUNCTION_NAME = "populateEpoch";
private static final String ENABLED_INPUT_FIELDS = "enabledInputFields";
private static final String JAVASCRIPT_RENDERED_KEY = "javascriptRenderedForDateTime";
private String dropDownClass = null;
private Logger log = Logger.getLogger(DateTimeTag.class);
public void setEpoch(String epoch)
{
this.epoch = epoch;
yearField = epoch + "year";
monthField = epoch + "month";
dayField = epoch + "day";
hourField = epoch + "hour";
minuteField = epoch + "minute";
}
public int doStartTag()
{
StringBuffer sb = new StringBuffer();
Calendar cal = getTime();
Object o = pageContext.getAttribute(JAVASCRIPT_RENDERED_KEY, PageContext.REQUEST_SCOPE);
if(o == null)
{
pageContext.setAttribute(JAVASCRIPT_RENDERED_KEY, new Object(), PageContext.REQUEST_SCOPE);
renderJavaScript(sb);
}
renderInputFields(sb, cal);
try
{
pageContext.getOut().print(sb.toString());
}catch(IOException e)
{
log.error(e);
}
return SKIP_BODY;
}
private void renderInputFields(StringBuffer sb, Calendar cal)
{
int startYear =2005;
int endYear = 2010;
sb.append("<table border=\"0\"><tr>");
sb.append("<td>Year</td>");
sb.append("<td>Month</td>");
sb.append("<td>Day</td>");
sb.append("<td>Hour</td>");
sb.append("<td>Minute</td>");
sb.append("</tr><tr>");
renderInputField(sb, yearField, startYear, endYear, cal.get(Calendar.YEAR), false);
renderInputField(sb, monthField, 0, 11, cal.get(Calendar.MONTH), true);
renderInputField(sb, dayField, 1, 31, cal.get(Calendar.DAY_OF_MONTH), false);
renderInputField(sb, hourField, 0, 23, cal.get(Calendar.HOUR_OF_DAY), false);
renderInputField(sb, minuteField, 0,59, cal.get(Calendar.MINUTE), false);
sb.append("<input type=\"hidden\" name=\"").append(epoch).append("\" id=\"");
sb.append(epoch).append("\" value=\"").append(cal.getTimeInMillis()).append("\">");
sb.append("</tr></table>");
}
private void renderInputField(StringBuffer sb, String name, int rangeStart, int rangeEnd, int value, boolean isMonth)
{
sb.append("<td><select id=\"" + name + "\" name=\"").append(name).append("\" class=\"").append(dropDownClass);
sb.append("\" onchange=\"").append(GET_DATE_FUNCTION_NAME).append("('").append(epoch).append("');\">\n");
int end = rangeEnd + 1;
for(int i = rangeStart; i <end; i++)
{
boolean selected = value == i;
sb.append("<option value=\"").append(i).append("\"");
if(selected)
sb.append(" SELECTED ");
sb.append(">");
int displayValue = i;
if(isMonth)
displayValue++;
sb.append(displayValue);
sb.append("</option>\n");
}
sb.append("</select></td>");
}
private void renderJavaScript(StringBuffer sb)
{
sb.append("<script language=\"javascript\">\n");
sb.append("function ").append(GET_DATE_FUNCTION_NAME).append("( baseID )\n{\n");
renderJavaScriptFields(sb, true);
sb.append("var dateValue = new Date(year, month, day, hour, minute, 0, 0);\n");
sb.append("var destField = document.getElementById(baseID);\n");
sb.append("destField.value = dateValue.getTime();\n");
sb.append("}\n");
sb.append("\n");
sb.append("function ").append(ENABLED_INPUT_FIELDS).append("( baseID, b )\n{\n");
renderJavaScriptFields(sb, false);
sb.append(" year.disabled = b;\n");
sb.append(" month.disabled = b;\n");
sb.append(" day.disabled = b;\n");
sb.append(" hour.disabled = b;\n");
sb.append(" minute.disabled = b;\n");
sb.append("}\n");
sb.append("</script>\n");
}
private void renderJavaScriptFields(StringBuffer sb, boolean value)
{
renderJavaScriptGetField(sb, "year", value);
renderJavaScriptGetField(sb, "month", value);
renderJavaScriptGetField(sb, "day", value);
renderJavaScriptGetField(sb, "hour", value);
renderJavaScriptGetField(sb, "minute", value);
}
private void renderJavaScriptGetField(StringBuffer sb, String id, boolean value)
{
String s = "var " + id + " = document.getElementById(baseID + '" + id + "');\n";
if(value)
s = s + id + " = " + id + ".value;\n";
sb.append(s);
}
private Calendar getTime()
{
String current = pageContext.getRequest().getParameter(epoch);
Calendar cal = null;
if(current != null)
{
try
{
long l = Long.parseLong(current);
Date date = new Date(l);
cal = Calendar.getInstance();
cal.setTime(date);
}catch(NumberFormatException ignore){}
}
if(cal == null)
{
cal = getEpochValue((HttpServletRequest)pageContext.getRequest());
}
String key = getKey((HttpServletRequest)pageContext.getRequest());
pageContext.getSession().setAttribute(key, cal);
return cal;
}
private Calendar getEpochValue(HttpServletRequest request)
{
Calendar cal = (Calendar)request.getSession().getAttribute(getKey(request));
if(cal != null)
{
return cal;
}
return Calendar.getInstance();
}
private String getKey(HttpServletRequest request)
{
String uri = request.getRequestURI();
int i = uri.indexOf('?');
if(i > 0)
uri = uri.substring(0, i);
String key = epoch + uri;
return key;
}
}