package net.sourceforge.ganttproject.gui.projectwizard;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.text.MessageFormat;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

import net.sourceforge.ganttproject.action.CancelAction;
import net.sourceforge.ganttproject.action.OkAction;
import net.sourceforge.ganttproject.gui.UIFacade;
import net.sourceforge.ganttproject.gui.options.TopPanel;
import net.sourceforge.ganttproject.language.GanttLanguage;

public abstract class WizardImpl {
    public class NextAction extends AbstractAction {
        NextAction() {
            super(GanttLanguage.getInstance().getText("next"));
        }

        public void actionPerformed(ActionEvent e) {
            WizardImpl.this.nextPage();
        }

    }

    public class BackAction extends AbstractAction {
        BackAction() {
            super(GanttLanguage.getInstance().getText("back"));
        }

        public void actionPerformed(ActionEvent e) {
            WizardImpl.this.backPage();
        }

    }

    private final ArrayList myPages = new ArrayList();

    private int myCurrentPage;

    private JPanel myPagesContainer;

    private CardLayout myCardLayout;

    private NextAction myNextAction;

    private BackAction myBackAction;

    private OkAction myOkAction;

    private UIFacade myUIFacade;

    private String myTitle;

    private CancelAction myCancelAction;

    private JPanel myPagesWrapper;

    private TopPanel myTitlePanel;

    public WizardImpl(UIFacade uiFacade, String title) {
        // super(frame, title, true);
        myUIFacade = uiFacade;
        myTitle = title;
        myCardLayout = new CardLayout();
        myPagesContainer = new JPanel(myCardLayout);
        myPagesWrapper = new JPanel(new BorderLayout());
        myNextAction = new NextAction();
        myBackAction = new BackAction();
    }

    public void nextPage() {
        if (myCurrentPage < myPages.size() - 1) {
            getCurrentPage().setActive(false);
            myCurrentPage++;
            getCurrentPage().setActive(true);
            myCardLayout.next(myPagesContainer);
        }
        adjustButtonState();
        updateTitleAndComment();
    }

    public void backPage() {
        if (myCurrentPage > 0) {
            getCurrentPage().setActive(false);
            myCurrentPage--;
            getCurrentPage().setActive(true);
            myCardLayout.previous(myPagesContainer);
        }
        adjustButtonState();
        updateTitleAndComment();
    }

    public void show() {
        for (int i = 0; i < myPages.size(); i++) {
            WizardPage nextPage = (WizardPage) myPages.get(i);
            //
            JPanel pagePanel = new JPanel(new BorderLayout());
            pagePanel.add(nextPage.getComponent());
            //
            myPagesContainer.add(pagePanel, nextPage.getTitle());
        }
        myCardLayout.first(myPagesContainer);
        myPagesContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//      TopPanel titlePanel = new TopPanel("New Project  ("
//      + GanttLanguage.getInstance().getText("step") + " "
//      + (i + 1) + " " + GanttLanguage.getInstance().getText("of")
//      + " " + (myPages.size()) + ")", null);
        myTitlePanel = new TopPanel("New Project", null);
        myPagesWrapper.add(myTitlePanel, BorderLayout.NORTH);
        myPagesWrapper.add(myPagesContainer, BorderLayout.CENTER);
        myOkAction = new OkAction() {
            public void actionPerformed(ActionEvent e) {
                onOkPressed();
            }
        };
        myCancelAction = new CancelAction() {
            public void actionPerformed(ActionEvent e) {
                onCancelPressed();
            }
        };
        adjustButtonState();
        updateTitleAndComment();
        getCurrentPage().setActive(true);
        myUIFacade.showDialog(myPagesWrapper, new Action[] { myBackAction,
                myNextAction, myOkAction, myCancelAction }, myTitle);
        /*
         * Box buttonBox = Box.createHorizontalBox(); JButton backButton =
         * createBackButton(); buttonBox.add(backButton);
         * buttonBox.add(Box.createHorizontalGlue()); JButton nextButton =
         * createNextButton(); buttonBox.add(nextButton);
         * buttonBox.add(Box.createHorizontalGlue()); JButton okButton =
         * createOkButton(); buttonBox.add(okButton);
         * getContentPane().setLayout(new BorderLayout());
         * getContentPane().add(myPagesContainer, BorderLayout.CENTER); //
         * JPanel buttonPanel = new JPanel(new BorderLayout());
         * buttonPanel.add(buttonBox, BorderLayout.EAST);
         * getContentPane().add(buttonPanel, BorderLayout.SOUTH); pack();
         * //setSize(300, 300); adjustButtonState(); DialogAligner.center(this,
         * getParent()); super.show();
         */
    }

    private void updateTitleAndComment() {
        myTitlePanel.setTitle(MessageFormat.format("  New Project (step {0} of {1})", new Object[] {
                new Integer(myCurrentPage+1), new Integer(myPages.size())
        }));
        StringBuffer comment = new StringBuffer("<html><body><ul>");
        for (int i=0; i<myPages.size(); i++) {
            WizardPage nextPage = (WizardPage) myPages.get(i);
            comment.append("<li>");
            if (i==myCurrentPage) {
                comment.append("<b>");
            }
            comment.append(nextPage.getTitle());
            if (i==myCurrentPage) {
                comment.append("</b>");
            }
            comment.append("</li>");
        }
        comment.append("</ul></body></html>");
        myTitlePanel.setComment(comment.toString());
    }
    protected void adjustButtonState() {
        myBackAction.setEnabled(true);
        myNextAction.setEnabled(true);
        if (myCurrentPage == 0) {
            myBackAction.setEnabled(false);
        }
        if (myCurrentPage == myPages.size() - 1) {
            myNextAction.setEnabled(false);
        }
        myOkAction.setEnabled(canFinish());
    }

    protected boolean canFinish() {
        return true;
    }

    protected void addPage(WizardPage page) {
        myPages.add(page);
    }

    protected void onOkPressed() {
        getCurrentPage().setActive(false);
    }

    private void onCancelPressed() {
        getCurrentPage().setActive(false);
    }

    private WizardPage getCurrentPage() {
        return (WizardPage) myPages.get(myCurrentPage);
    }

    protected UIFacade getUIFacade() {
        return myUIFacade;
    }

}
