/*
 * Copyright
 *   2008 axYus - www.axyus.com
 *   2008 C.Bosquet - charles.bosquet@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package fr.gouv.finances.dgfip.xemelios.web.gwt.client.widget;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import fr.gouv.finances.dgfip.xemelios.web.gwt.client.utils.GWTUtils;
import java.util.ArrayList;
import java.util.EventListener;

/**
 * @author CBO
 */
public class PaginationWidget extends Composite {

    private HorizontalPanel horizontalPanel;
    private PaginationInfo paginationInfo;
//    private ImageButton firstButton;
//    private ImageButton previousButton;
//    private ImageButton nextButton;
//    private ImageButton lastButton;
    private Image firstButton;
    private Image previousButton;
    private Image nextButton;
    private Image lastButton;
    private ListBox lb;
    private HTML label1, label2;
    private ChangePageRequestListenerCollection changePageRequestListenerCollection = new ChangePageRequestListenerCollection();

    public PaginationWidget() {
        this.horizontalPanel = new HorizontalPanel();
//        this.firstButton = new ImageButton(GWTUtils.getContextPath() + "img/first-page.gif", GWTUtils.getContextPath() + "img/first-page.gif", new HTML("Premi&egrave;re page").getHTML());
//        this.previousButton = new ImageButton(GWTUtils.getContextPath() + "img/previous-page.gif", GWTUtils.getContextPath() + "img/previous-page.gif", new HTML("Page pr&eacute;c&eacute;dente").getHTML());
//        this.nextButton = new ImageButton(GWTUtils.getContextPath() + "img/next-page.gif", GWTUtils.getContextPath() + "img/next-page.gif", new HTML("Page suivante").getHTML());
//        this.lastButton = new ImageButton(GWTUtils.getContextPath() + "img/last-page.gif", GWTUtils.getContextPath() + "img/last-page.gif", new HTML("Derni&egrave;re page").getHTML());
        this.firstButton = new Image(GWTUtils.getContextPath() + "img/first-page.gif");
        firstButton.setTitle(new HTML("Premi&egrave;re page").getHTML());
        this.previousButton = new Image(GWTUtils.getContextPath() + "img/previous-page.gif");
        previousButton.setTitle(new HTML("Page pr&eacute;c&eacute;dente").getHTML());
        this.nextButton = new Image(GWTUtils.getContextPath() + "img/next-page.gif");
        nextButton.setTitle(new HTML("Page suivante").getHTML());
        this.lastButton = new Image(GWTUtils.getContextPath() + "img/last-page.gif");
        lastButton.setTitle(new HTML("Derni&egrave;re page").getHTML());
        horizontalPanel.add(this.firstButton);
        horizontalPanel.add(new HTML("&nbsp;"));
        horizontalPanel.add(this.previousButton);
        horizontalPanel.getElement().setId("PageNavigation");
        label1 = new HTML("&nbsp;");
        horizontalPanel.add(label1);
        horizontalPanel.add(lb=new ListBox());
        label2 = new HTML("&nbsp;");
        horizontalPanel.add(label2);
        horizontalPanel.add(this.nextButton);
        horizontalPanel.add(new HTML("&nbsp;"));
        horizontalPanel.add(this.lastButton);
        update();
        this.firstButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                if(hasPrevious())
                    changePageRequestListenerCollection.fireChangePageRequest(PaginationWidget.this, 0);
            }
        });
        this.previousButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                if(hasPrevious())
                    changePageRequestListenerCollection.fireChangePageRequest(PaginationWidget.this, PaginationWidget.this.paginationInfo.getCurrentPageNumber() - 1);
            }
        });
        this.nextButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                if(hasNext())
                    changePageRequestListenerCollection.fireChangePageRequest(PaginationWidget.this, PaginationWidget.this.paginationInfo.getCurrentPageNumber() + 1);
            }
        });
        this.lastButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                if(hasNext())
                    changePageRequestListenerCollection.fireChangePageRequest(PaginationWidget.this, PaginationWidget.this.paginationInfo.getPageCount() - 1);
            }
        });
        this.lb.addChangeListener(new ChangeListener() {
            public void onChange(Widget sender) {
                int index = lb.getSelectedIndex();
                changePageRequestListenerCollection.fireChangePageRequest(PaginationWidget.this, index);
            }
        });
        initWidget(this.horizontalPanel);
    }

    public void setPaginationInfo(PaginationInfo paginationInfo) {
        this.paginationInfo = paginationInfo;
        update();
    }

    public void addChangePageRequestListener(ChangePageRequestListener changePageRequestListener) {
        changePageRequestListenerCollection.add(changePageRequestListener);
    }

    private void update() {
        if(paginationInfo!=null && paginationInfo.getPageCount()>0) {
            label1.setHTML("&nbsp;Page&nbsp;");
            label2.setHTML("&nbsp;/&nbsp;"+paginationInfo.getPageCount()+"&nbsp;");
            lb.clear();
            for(int i=0;i<paginationInfo.getPageCount();i++) {
                lb.addItem(Integer.toString(i+1),Integer.toString(i));
            }
            lb.setSelectedIndex(paginationInfo.getCurrentPageNumber());
            lb.setEnabled(true);
        } else {
            label1.setHTML("&nbsp;");
            label2.setHTML("&nbsp;");
            lb.clear();
            lb.setEnabled(false);
        }
    }

    private boolean hasNext() {
        return this.paginationInfo != null && this.paginationInfo.getCurrentPageNumber() < (this.paginationInfo.getPageCount() - 1);
    }

    private boolean hasPrevious() {
        return this.paginationInfo != null && this.paginationInfo.getCurrentPageNumber() > 0;
    }

    static public interface PaginationInfo {

        static public PaginationInfo emptyPage = new PaginationInfo() {

            public int getPageCount() {
                return 0;
            }

            public int getCurrentPageNumber() {
                return -1;
            }
        };

        int getPageCount();

        int getCurrentPageNumber();
    }

    static public interface ChangePageRequestListener extends EventListener {

        void onChangePageRequest(PaginationWidget sender, int requestedPageNumber);
    }

    static private class ChangePageRequestListenerCollection extends ArrayList<ChangePageRequestListener> {

        public void fireChangePageRequest(PaginationWidget sender, int requestedPageNumber) {
            for (ChangePageRequestListener listener : this) {
                listener.onChangePageRequest(sender,requestedPageNumber);
            }
        }
    }
}
