package net.sf.egonet.web.panel; import java.util.ArrayList; import java.util.List; import java.util.Arrays; import java.util.StringTokenizer; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.RadioChoice; import com.google.common.collect.Lists; import net.sf.egonet.model.Alter; import net.sf.egonet.model.Answer; import net.sf.egonet.model.Question; import net.sf.egonet.model.Answer.SkipReason; import net.sf.egonet.web.component.FocusOnLoadBehavior; import net.sf.egonet.web.component.TextField; import net.sf.egonet.web.panel.TimeSpanAnswerFormFieldPanel; public class DateAnswerFormFieldPanel extends AnswerFormFieldPanel { private static final List<String> MONTHS = Arrays.asList(new String[] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }); private static final List<String> AM_PM = Arrays.asList(new String[] { "AM", "PM" }); private boolean useYears; private boolean useMonths; private boolean useDays; private boolean useHours; private boolean useMinutes; private String theYear; private String theMonth; private String theDay; private String theHour; private String theMinute; private String amHour; private int yearValue; // int values of corresponding strings private int dayValue; private int hourValue; private int minuteValue; private TextField inputYear; private DropDownChoice inputMonth; private TextField inputDay; private TextField inputHour; private TextField inputMinute; private RadioChoice radioAmPm; private Label lblYear; private Label lblHour; private String lblYearPrompt; private String lblHourPrompt; private CheckboxesPanel<String> refDKCheck; public DateAnswerFormFieldPanel(String id, Question question, ArrayList<Alter> alters, Long interviewId) { super(id,question,Answer.SkipReason.NONE,alters, interviewId); stringToCalendar(""); build(""); } public DateAnswerFormFieldPanel(String id, Question question, String answer, Answer.SkipReason skipReason, ArrayList<Alter> alters, Long interviewId) { super(id,question,skipReason,alters,interviewId); stringToCalendar(answer); build(answer); } /** * 'our' string representation of a date will be * MMM DD YYYY HH:MM AM/PM * where MMM is month in a string form (see MONTHS above) * This is a tremendous simplification over any of the string * representations intrinsic to the calendar class * @param strDate a date or time span, in string format * @return */ private boolean stringToCalendar ( String strDate ) { int iTokens; StringTokenizer strk; String strAmPm; theYear = ""; theMonth = "January"; theDay = ""; theHour = ""; theMinute = ""; amHour = "AM"; if ( strDate!=null && strDate.length()>0 ) { strk = new StringTokenizer(strDate.trim(), " :"); iTokens = strk.countTokens(); if ( iTokens>0 ) // Month theMonth = strk.nextToken(); if ( iTokens>1 ) // day in the month theDay = strk.nextToken(); if ( iTokens>2 ) //year theYear = strk.nextToken(); if ( iTokens>3 ) // hour theHour = strk.nextToken(); if ( iTokens>4 ) // minute theMinute = strk.nextToken(); if ( iTokens>5 ) { // AM / PM strAmPm = strk.nextToken(); if ( strAmPm.trim().equalsIgnoreCase("PM") || strAmPm.trim().equalsIgnoreCase("P.M.")) { amHour = "PM"; } else { amHour = "AM"; } } } return(true); } /** * 'collects' the year, month and day data and creates a * string * @return string representation of the date */ private String calendarToString() { String strDate = new String(); if ( theDay.isEmpty() && theYear.isEmpty() && theHour.isEmpty() && theMinute.isEmpty() ) return(strDate); strDate = String.format ("%s %s %s %s:%s %s", (theMonth.isEmpty() ? "MM" : theMonth), (theDay.isEmpty() ? "1" : theDay), (theYear.isEmpty() ? "0000" : theYear), (theHour.isEmpty() ? "12" : theHour), (theMinute.isEmpty()? "00" : theMinute), amHour); return(strDate); } private void build(String answer) { int iTimeUnits = question.getTimeUnits(); useYears = ((iTimeUnits & TimeSpanAnswerFormFieldPanel.BIT_YEAR)>0 ) ? true : false; useMonths = ((iTimeUnits & TimeSpanAnswerFormFieldPanel.BIT_MONTH)>0 ) ? true : false; useDays = ((iTimeUnits & TimeSpanAnswerFormFieldPanel.BIT_DAY)>0 ) ? true : false; useHours = ((iTimeUnits & TimeSpanAnswerFormFieldPanel.BIT_HOUR)>0 ) ? true : false; useMinutes = ((iTimeUnits & TimeSpanAnswerFormFieldPanel.BIT_MINUTE)>0 ) ? true : false; lblYearPrompt = " Date ("; if ( useMonths ) lblYearPrompt += "Month,"; if ( useDays ) lblYearPrompt += "Day,"; if ( useYears ) lblYearPrompt += "Year"; lblYearPrompt += ")"; lblHourPrompt = "Time "; if ( useHours && useMinutes ) lblHourPrompt += "(HH:MM)"; else if ( useHours) lblHourPrompt += "(Hours)"; else if ( useMinutes ) lblHourPrompt += "(Minutes)"; inputYear = new TextField ("Year", new PropertyModel(this, "theYear"), String.class); inputMonth = new DropDownChoice("Month", new PropertyModel(this,"theMonth"), MONTHS); add(inputMonth); inputDay = new TextField("Day", new PropertyModel(this,"theDay"), String.class); inputHour = new TextField("Hour", new PropertyModel(this,"theHour"), String.class); inputMinute = new TextField("Minute", new PropertyModel(this,"theMinute"), String.class); radioAmPm = new RadioChoice ("ampm", new PropertyModel(this, "amHour"), AM_PM); radioAmPm.setPrefix("<span style=\"white-space:nowrap;\">"); radioAmPm.setSuffix( "</span><span style=\"white-space:pre-wrap; color:#ffffff\"> . . </span>"); add(inputMinute); add(inputHour); add(radioAmPm); add(inputDay); add(inputMonth); add(inputYear); lblYear = new Label("lblYear", lblYearPrompt); lblHour = new Label("lblHour", lblHourPrompt); add(lblYear); add(lblHour); inputYear.setVisible(useYears); if ( useYears || useMonths || useDays ) lblYear.setVisible(true); else lblYear.setVisible(false); inputMonth.setVisible(useMonths); inputDay.setVisible(useDays); inputHour.setVisible(useHours); if ( useHours || useMinutes) lblHour.setVisible(true); else lblHour.setVisible(false); radioAmPm.setVisible(useHours); inputMinute.setVisible(useMinutes); ArrayList<String> refAndDK = Lists.newArrayList(); if ( !question.getType().equals(Question.QuestionType.EGO_ID)) { if ( question.getDontKnowButton()) refAndDK.add(dontKnow); if ( question.getRefuseButton()) refAndDK.add(refuse); } ArrayList<String> selectedRefAndDK = Lists.newArrayList(); if(originalSkipReason.equals(SkipReason.DONT_KNOW)) { selectedRefAndDK.add(dontKnow); } if(originalSkipReason.equals(SkipReason.REFUSE)) { selectedRefAndDK.add(refuse); } refDKCheck = new CheckboxesPanel<String>("refDKCheck", refAndDK,selectedRefAndDK); add(refDKCheck); } /** * returns the string used if an incorrect number of checkboxes * are selected to prompt the user to check more or fewer */ public String getRangeCheckNotification() { String strNotification = ""; if ( dontKnow() || refused()) return(strNotification); if ( useYears ) { theYear = theYear.trim(); try { yearValue = Integer.parseInt(theYear); } catch ( NumberFormatException nfeYear) { yearValue = 1000; strNotification += " Non-digits in year field"; } if ( yearValue < 1000 ) strNotification += "Year too low "; if ( yearValue > 9999 ) strNotification += "Year too high "; } if ( useDays ) { theDay = theDay.trim(); try { dayValue = Integer.parseInt(theDay); } catch ( NumberFormatException nfeDay) { dayValue = 1; strNotification += " Non-digits in day field"; } if ( dayValue<1 ) strNotification += "Day too low "; if (dayValue>31 ) strNotification += "Day too high "; } if ( useHours ) { theHour = theHour.trim(); try { hourValue = Integer.parseInt(theHour); } catch ( NumberFormatException nfeHour) { hourValue = 1; strNotification += " Non-digits in hour field"; } if ( hourValue<1 ) strNotification += "Hour too low "; if ( hourValue>12 ) strNotification += "Hour too high "; } if ( useMinutes ) { theMinute = theMinute.trim(); try { minuteValue = Integer.parseInt(theMinute); } catch ( NumberFormatException nfeMinute ) { minuteValue = 1; strNotification += " Non-digits in minute field"; } if ( minuteValue<0 ) strNotification += "Minute too low "; if ( minuteValue>59 ) strNotification += "Minute too high "; } return(strNotification); } /** * if the user selected dontKnow or refused to answer a question * don't bother checking the responses. */ public boolean rangeCheckOkay() { if ( dontKnow() || refused()) return (true); if ( useYears ) { theYear = theYear.trim(); try { yearValue = Integer.parseInt(theYear); } catch ( NumberFormatException nfeYear) { yearValue = 1000; return(false); } if ( yearValue < 1000 || yearValue > 9999 ) return(false); } if ( useDays ) { theDay = theDay.trim(); try { dayValue = Integer.parseInt(theDay); } catch ( NumberFormatException nfeDay) { dayValue = 1; return(false); } if ( dayValue<1 || dayValue>31 ) return(false); } if ( useHours ) { theHour = theHour.trim(); try { hourValue = Integer.parseInt(theHour); } catch ( NumberFormatException nfeHour) { hourValue = 1; return(false); } if ( hourValue<1 || hourValue>12 ) return(false); } if ( useMinutes ) { theMinute = theMinute.trim(); try { minuteValue = Integer.parseInt(theMinute); } catch ( NumberFormatException nfeMinute ) { minuteValue = 1; return(false); } if ( minuteValue<0 || minuteValue>59 ) return(false); } return(true); } public String getAnswer() { return (calendarToString()); } public void setTheYear ( String theYear ) { this.theYear = (theYear==null) ? "" : theYear; } public String getTheYear() { return (theYear);} public void setTheMonth ( String theMonth ) { this.theMonth = (theMonth==null) ? "Jan" : theMonth; } public String getTheMonth() { return (theMonth);} public void setTheDay ( String theDay ) { this.theDay = (theDay==null) ? "" : theDay; } public String getTheDay() { return (theDay);} public void setTheHour ( String theHour ) { this.theHour = (theHour==null) ? "" : theHour; } public String getTheHour() { return (theHour);} public void setTheMinute ( String theMinute ) { this.theMinute = (theMinute==null)? "" : theMinute; } public String getTheMinute() { return (theMinute);} public void setAmHour ( String amHour ) { this.amHour = (amHour==null) ? "AM" : amHour; } public String getAmHour() { return (amHour);} public void setAutoFocus() { if (inputHour.isVisible()) { inputHour.add(new FocusOnLoadBehavior()); return; } if (inputMinute.isVisible()) { inputMinute.add(new FocusOnLoadBehavior()); return; } if (inputDay.isVisible()) { inputDay.add(new FocusOnLoadBehavior()); return; } if (inputMonth.isVisible()) { inputMonth.add(new FocusOnLoadBehavior()); return; } if (inputYear.isVisible()) { inputYear.add(new FocusOnLoadBehavior()); return; } } public boolean dontKnow() { return refDKCheck.getSelected().contains(dontKnow); } public boolean refused() { return refDKCheck.getSelected().contains(refuse); } }