/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.trinidaddemo.composite;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.NumberConverter;
import javax.faces.render.Renderer;
import javax.faces.validator.LongRangeValidator;

import org.apache.myfaces.trinidad.component.core.input.CoreInputText;

/**
 * An experiment in building a renderer that uses a composite
 * component strategy to render.  Some basic principles:
 * <ul>
 * <li> The child components get re-created on each pass through
 *    the system;  this means seeing if they exist in both Apply Request
 *    Values (<code>decode()</code>) and Render Response
 *    (<code>encodeBegin()</code>), and marking the components
 *    transient so they don't get saved.
 * <li> The model is the tricky part:  instead of using real
 *   <code>ValueBindings</code> on the children, I let them
 *   use local values, and then manully transfer over their local values
 *   into an overall "local value" during validate().  Unfortunately,
 *   using ValueBindings to automate the transfer wouldn't quite work,
 *   since the transfer wouldn't happen 'til Update Model, which is
 *   too late to preserve the semantics of an editable value component in JSF.
 * </ul>
 */
public class DateFieldAsRenderer extends Renderer
{
  @SuppressWarnings("unchecked")
  @Override
  public void decode(FacesContext context, UIComponent component)
  {
    _addChildren(context, component);

    Map<String, Object> attrs = component.getAttributes();
    if (Boolean.TRUE.equals(attrs.get("readOnly")) ||
        Boolean.TRUE.equals(attrs.get("disabled")))
      return;

    // Just clue in component that we have been "submitted" so
    // that it doesn't short-circuit anything
    EditableValueHolder evh = (EditableValueHolder) component;
    evh.setSubmittedValue(Boolean.TRUE);

    // Because these components weren't around during processDecodes(),
    // they didn't get decoded.  So, run that now.
    component.getFacet("month").processDecodes(context);
    component.getFacet("year").processDecodes(context);
    component.getFacet("day").processDecodes(context);
  }

  @Override
  public Object getConvertedValue(
    FacesContext context,
    UIComponent  component,
    Object       submittedValue)
  {
    EditableValueHolder monthComp = (EditableValueHolder) component.getFacet("month");
    EditableValueHolder yearComp = (EditableValueHolder) component.getFacet("year");
    EditableValueHolder dayComp = (EditableValueHolder) component.getFacet("day");

    if (!monthComp.isValid() ||
        !yearComp.isValid() ||
        !dayComp.isValid())
    {
      // =-=AEW What to do????????
      //setValid(false);
      return null;
    }

    int year = ((Number) yearComp.getValue()).intValue();
    // We'll be 1970 - 2069.  Good enough for a demo.
    if (year < 70)
      year += 100;

    int month = ((Number) monthComp.getValue()).intValue() - 1;
    int day = ((Number) dayComp.getValue()).intValue();

    Date oldValue = (Date) ((EditableValueHolder) component).getValue();
    //Date newValue = (Date) oldValue.clone();
    Calendar calendar = Calendar.getInstance();
    calendar.setLenient(true);
    calendar.setTime(oldValue);
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.MONTH, month);
    calendar.set(Calendar.DAY_OF_MONTH, day);
    
    // Invalid day given the month
    if (day != calendar.get(Calendar.DAY_OF_MONTH))
    {
      int numberOfDaysInMonth = day - calendar.get(Calendar.DAY_OF_MONTH);
      FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Invalid date.",
                    "This month only has " + numberOfDaysInMonth + " days!");
      throw new ConverterException(message);
    }

    return calendar.getTime();
  }

  @Override
  public void encodeBegin(FacesContext context,
                          UIComponent component) throws IOException
  {
    _addChildren(context, component);
  }

  @Override
  public void encodeChildren(FacesContext context,
                             UIComponent component) throws IOException
  {
    ResponseWriter out = context.getResponseWriter();

    UIComponent month = component.getFacet("month");
    month.encodeBegin(context);
    month.encodeChildren(context);
    month.encodeEnd(context);

    out.writeText("\u00a0/\u00a0", null);

    UIComponent day = component.getFacet("day");
    day.encodeBegin(context);
    day.encodeChildren(context);
    day.encodeEnd(context);

    out.writeText("\u00a0/\u00a0", null);

    UIComponent year = component.getFacet("year");
    year.encodeBegin(context);
    year.encodeChildren(context);
    year.encodeEnd(context);
  }

  @Override
  public boolean getRendersChildren()
  {
    return true;
  }

  @SuppressWarnings("unchecked")
  private void _addChildren(FacesContext context, UIComponent component)
  {
    // If the components are already there, bail.
    if (component.getFacet("month") != null)
      return;

    String id = component.getId();
    if (id == null)
    {
      id = context.getViewRoot().createUniqueId();
      component.setId(id);
    }

    Map<String, UIComponent> facets = component.getFacets();
    facets.clear();

    Date value = (Date) ((EditableValueHolder) component).getValue();
    Calendar calendar = null;
    if(value != null)
    {
      calendar = Calendar.getInstance();
      calendar.setLenient(true);
      calendar.setTime(value);
    }

    CoreInputText month = _createTwoDigitInput(context);
    month.setShortDesc("Month");
    month.setId(id + "_month");

    LongRangeValidator monthRange = _createLongRangeValidator(context);
    monthRange.setMinimum(1);
    monthRange.setMaximum(12);
    month.addValidator(monthRange);
    if (value != null)
      month.setValue(new Integer(calendar.get(Calendar.MONTH) + 1));
    facets.put("month", month);

    CoreInputText day = _createTwoDigitInput(context);
    day.setShortDesc("Day");
    day.setId(id + "_day");
    LongRangeValidator dayRange = _createLongRangeValidator(context);
    dayRange.setMinimum(1);
    dayRange.setMaximum(31);
    day.addValidator(dayRange);
    if (value != null)
      day.setValue(new Integer(calendar.get(Calendar.DAY_OF_MONTH)));
    facets.put("day", day);

    CoreInputText year = _createTwoDigitInput(context);
    year.setShortDesc("Year");
    year.setId(id + "_year");
    if (value != null)
    {
      int yearValue = calendar.get(Calendar.YEAR) - 1900;
      if (yearValue >= 100)
        yearValue -= 100;
      year.setValue(new Integer(yearValue));
    }

    facets.put("year", year);
  }

  private LongRangeValidator _createLongRangeValidator(FacesContext context)
  {
    return (LongRangeValidator)
      context.getApplication().createValidator(LongRangeValidator.VALIDATOR_ID);
  }

  private CoreInputText _createTwoDigitInput(FacesContext context)
  {
    CoreInputText input = new CoreInputText();
    input.setColumns(2);
    input.setMaximumLength(2);
    input.setTransient(true);
    input.setRequired(true);
    input.setSimple(true);

    NumberConverter converter = (NumberConverter)
      context.getApplication().createConverter(NumberConverter.CONVERTER_ID);
    converter.setIntegerOnly(true);
    converter.setMaxIntegerDigits(2);
    converter.setMinIntegerDigits(2);
    input.setConverter(converter);

    return input;
  }
}
