package com.sfr.bios.rc.client.ui.baseComponent;

import static com.sfr.bios.rc.client.ui.utils.DateUtil.getAnneeFromDate;
import static com.sfr.bios.rc.client.ui.utils.DateUtil.getNumMoisFromDate;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.constants.DateTimeConstants;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.MonthSelector;

/**
 * Classe permettant de customiser le selecteur de mois et d'années du calendrier de GWT-Incubator à la sauce BIOS pour
 * le composant SDT.
 * 
 * @author AAUBRY
 */
public class SDTMonthSelector
    extends MonthSelector
{

    private PushButton backwards;

    private PushButton forwards;

    private ListBox mois;

    private ListBox annee;

    private BTSPoussoir croixFermeture;

    private Grid grid;

    private Date fromRange;

    private Date toRange;

    public SDTMonthSelector()
    {
        super();
        fromRange = new Date();
        CalendarUtil.addMonthsToDate( fromRange, ( -100 ) * 12 );
        toRange = new Date();
        CalendarUtil.addMonthsToDate( toRange, 100 * 12 );
    }

    public SDTMonthSelector( Date from, Date to )
    {
        super();
        this.setAllowableDateRange( from, to );
    }

    private static final DateTimeConstants defaultDateTimeConstants =
        (DateTimeConstants) GWT.create( DateTimeConstants.class );

    /**
     * {@inheritDoc}
     *
     * @see com.google.gwt.gen2.datepicker.client.MonthSelector#setAllowableDateRange(java.util.Date, java.util.Date)
     */
    public void setAllowableDateRange( Date from, Date to )
    {
        this.fromRange = from;
        this.toRange = to;
    }

    /**
     * {@inheritDoc}
     *
     * @see com.google.gwt.gen2.datepicker.client.DatePickerComponent#refresh()
     */
    @Override
    protected void refresh()
    {

        int year = getAnneeFromDate( getModel().getCurrentMonth() );
        String yearString = String.valueOf( year );
        int oldIndexAnnee = annee.getSelectedIndex();
        int newIndexAnnee = rechercherIndexFromListBoxByItem( annee, yearString );
        annee.setSelectedIndex( newIndexAnnee );

        if ( oldIndexAnnee != newIndexAnnee )
        {
            reinitListBoxMois();
        }

        int month = getNumMoisFromDate( getModel().getCurrentMonth() );
        setSelectedMonth( month );

        if ( year == getAnneeFromDate( fromRange ) && month == getNumMoisFromDate( fromRange ) )
        {
            backwards.setVisible( false );
        }
        else
        {
            backwards.setVisible( true );
        }

        if ( year == getAnneeFromDate( toRange ) && month == getNumMoisFromDate( toRange ) )
        {
            forwards.setVisible( false );
        }
        else
        {
            forwards.setVisible( true );
        }
    }

    /**
     * @param month
     */
    private void setSelectedMonth( int month )
    {
        for ( int index = 0; index < mois.getItemCount(); index++ )
        {
            int value = Integer.parseInt( mois.getValue( index ) );
            if ( value == month )
            {
                mois.setSelectedIndex( index );
            }
        }
    }

    /**
     * {@inheritDoc}
     *
     * @see com.google.gwt.gen2.datepicker.client.DatePickerComponent#setup()
     */
    @Override
    protected void setup()
    {
        // Set up backwards.
        backwards = new PushButton();
        backwards.addClickHandler( new ClickHandler()
        {
            public void onClick( ClickEvent event )
            {
                addMonths( -1 );
            }
        } );

        backwards.getUpFace().setHTML( "&laquo;" );
        // backwards.setStyleName( previousButtonCss() );

        mois = new ListBox();
        reinitListBoxMois();

        mois.addChangeHandler( new ChangeHandler()
        {

            public void onChange( ChangeEvent event )
            {
                int indexSelectionne = mois.getSelectedIndex();
                int numMois = Integer.parseInt( mois.getValue( indexSelectionne ) );
                int offset = numMois - getNumMoisFromDate( getModel().getCurrentMonth() );
                addMonths( offset );
            }
        } );

        annee = new ListBox();
        for ( int index = getAnneeFromDate( this.fromRange ); index <= getAnneeFromDate( this.toRange ); index++ )
        {
            annee.addItem( String.valueOf( index ) );
        }
        annee.addChangeHandler( new ChangeHandler()
        {

            public void onChange( ChangeEvent event )
            {
                int indexSelectionne = annee.getSelectedIndex();
                int anneeSelectionee = Integer.parseInt( annee.getItemText( indexSelectionne ) );
                int currentNumMois = getNumMoisFromDate( getModel().getCurrentMonth() );
                if ( anneeSelectionee == getAnneeFromDate( fromRange )
                    && currentNumMois < getNumMoisFromDate( fromRange ) )
                {
                    getModel().setCurrentMonth( fromRange );
                    refreshAll();
                }
                else if ( anneeSelectionee == getAnneeFromDate( toRange )
                    && currentNumMois > getNumMoisFromDate( toRange ) )
                {
                    getModel().setCurrentMonth( toRange );
                    refreshAll();
                }
                else
                {
                    int offset = anneeSelectionee - getAnneeFromDate( getModel().getCurrentMonth() );
                    addMonths( 12 * offset );
                }

                reinitListBoxMois();
                int month = getNumMoisFromDate( getModel().getCurrentMonth() );
                setSelectedMonth( month );
            }
        } );

        forwards = new PushButton();
        forwards.getUpFace().setHTML( "&raquo;" );
        // forwards.setStyleName( nextButtonCss() );
        forwards.addClickHandler( new ClickHandler()
        {
            public void onClick( ClickEvent event )
            {
                addMonths( +1 );
            }
        } );

        croixFermeture = new BTSPoussoir( new Image( "images/btn_cancel.gif" ) );
        // Set up grid.
        grid = new Grid( 1, 5 );
        grid.setWidget( 0, 0, backwards );
        grid.setWidget( 0, 1, mois );
        grid.setWidget( 0, 2, annee );
        grid.setWidget( 0, 3, forwards );
        grid.setWidget( 0, 4, croixFermeture );

        CellFormatter formatter = grid.getCellFormatter();
        // formatter.setStyleName( 0, 1, monthCss() );
        formatter.setWidth( 0, 0, "10%" );
        formatter.setWidth( 0, 3, "10%" );
        formatter.setWidth( 0, 4, "20%" );
        formatter.setAlignment( 0, 4, HasHorizontalAlignment.ALIGN_RIGHT, HasVerticalAlignment.ALIGN_TOP );
        // grid.setStyleName( daysCss() );
        initWidget( grid );

    }

    /**
     * {@inheritDoc}
     *
     * @see com.google.gwt.user.datepicker.client.MonthSelectorPublic#addMonths(int)
     */
    protected void addMonths( int numMonths )
    {
        super.addMonths( numMonths );
    }

    /**
     * Reinitialise le listBox représentant les mois lorsque l'on change d'année
     */
    private void reinitListBoxMois()
    {
        mois.clear();
        int currentYear = getAnneeFromDate( getModel().getCurrentMonth() );
        int currentMonth = getNumMoisFromDate( getModel().getCurrentMonth() );
        String[] shortMonths = defaultDateTimeConstants.shortMonths();
        for ( int index = 0; index < shortMonths.length; index++ )
        {
            if ( !( currentYear == getAnneeFromDate( fromRange ) && index < getNumMoisFromDate( fromRange ) )
                && !( currentYear == getAnneeFromDate( toRange ) && index > getNumMoisFromDate( toRange ) ) )
            {
                mois.addItem( shortMonths[index], String.valueOf( index ) );
                if ( index == currentMonth )
                {
                    mois.setSelectedIndex( index );
                }
            }
        }

    }

    /**
     * Retourne l'index de l'item
     * 
     * @param liste
     * @param item
     * @return
     */
    private static int rechercherIndexFromListBoxByItem( ListBox liste, String item )
    {
        if ( null != liste && null != item )
        {
            for ( int index = 0; index < liste.getItemCount(); index++ )
            {
                if ( item.equals( liste.getItemText( index ) ) )
                {
                    return index;
                }
            }
        }
        return 0;
    }

    /**
     * @return the croixFermeture
     */
    public BTSPoussoir getCroixFermeture()
    {
        return croixFermeture;
    }

}
