/*******************************************************************************
 * 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.ofbiz.pos.screen;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import javolution.util.FastMap;
import net.xoetrope.swing.XButton;
import net.xoetrope.swing.XDialog;
import net.xoetrope.swing.XList;
import net.xoetrope.swing.XScrollPane;
import net.xoetrope.xui.XPage;
import net.xoetrope.xui.events.XEventHelper;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.pos.PosTransaction;
import org.ofbiz.product.config.ProductConfigWrapper;
import org.ofbiz.product.config.ProductConfigWrapper.ConfigItem;
import org.ofbiz.product.config.ProductConfigWrapper.ConfigOption;


@SuppressWarnings("serial")
public class ConfigureItem extends XPage {

    /**
     * To create or configure a configurable item
     */

    public static final String module = ConfigureItem.class.getName();
    protected PosScreen m_pos = null;
    protected ConfigureItem m_configureItem = null;
    protected XDialog m_dialog = null;
    protected XList m_configList = null;
    protected XList m_optionList = null;
    protected XButton m_ok = null;
    protected XButton m_reset = null;
    protected XScrollPane m_optionListPane = null;
    protected PosTransaction m_trans = null;
    protected static final String buttonArray[][] = {
        { "r1c1", "r1c2", "r1c3", "r1c4" },
        { "r2c1", "r2c2", "r2c3", "r2c4" },
        { "r3c1", "r3c2", "r3c3", "r3c4" },
        { "r4c1", "r4c2", "r4c3", "r4c4" }
    };
    protected ProductConfigWrapper m_pcw = null;
    protected List<XButton> m_buttonList = null;
    protected Map<String, Question> questionHashMap = null;

    public ConfigureItem(ProductConfigWrapper pcw, PosTransaction trans, PosScreen page) {
        m_pcw = pcw;
        m_trans = trans;
        m_pos = page;
        m_configureItem = this;
    }

    public ProductConfigWrapper openDlg() {
        // cache must be set to false because there's no method to remove actionhandlers
        m_dialog = (XDialog) pageMgr.loadPage(
                m_pos.getScreenLocation() + "/dialog/ConfigureItem", false);
        m_dialog.setCaption(UtilProperties.getMessage(PosTransaction.resource, "PosConfigureItem", Locale.getDefault()));

        m_optionListPane = (XScrollPane) m_dialog.findComponent("optionListPane");
        m_configList = (XList) m_dialog.findComponent("configList");
        m_optionList = (XList) m_dialog.findComponent("optionList");
        m_ok = (XButton) m_dialog.findComponent("BtnOk");
        m_reset = (XButton) m_dialog.findComponent("BtnReset");

        XEventHelper.addMouseHandler(this, m_ok, "ok");
        XEventHelper.addMouseHandler(this, m_reset, "reset");

        getButtons();
        //debugQuestions();
        showItem();
        displayQuestions();
        m_dialog.pack();
        m_dialog.showDialog(this);

        return m_pcw;
    }

    public synchronized void ok() {
        if (wasMouseClicked()) {
            closeDlg();
        }
    }

    public synchronized void reset() {
        if (wasMouseClicked()) {
            m_pcw.setDefaultConfig();
            resetButtons();
            showItem();
            m_dialog.repaint();
        }
    }

    public synchronized void buttonPressed() {
        if (wasMouseClicked()) {
            EventObject eo = getCurrentEvent();
            XButton button = (XButton) eo.getSource();
            Question question = questionHashMap.get(button.getName());
            question.buttonClicked();
            showItem();
            m_dialog.repaint();
            return;
        }
    }

    public synchronized void listPressed() {
        showItem();
        m_dialog.repaint();
        return;
    }


    private void closeDlg() {
        m_dialog.closeDlg();
    }

    private void resetButtons() {
        Object[] questions = questionHashMap.values().toArray();
        for (Object question : questions) {
            ((Question)question).reset();
        }
        return;
    }

    private void showItem() {
        DefaultListModel listModel = null;
        listModel = new DefaultListModel();

        GenericValue gv = m_pcw.getProduct();
        listModel.addElement(gv.get("description"));

        List<ConfigItem> questions = m_pcw.getQuestions();
        for (ConfigItem question : questions) {
            List<ConfigOption> options = question.getOptions();
            for (ConfigOption configoption : options) {
                if (configoption.isSelected()) {
                    listModel.addElement("  "+configoption.getDescription());
                }
            }
        }
        m_configList.setModel(listModel);
        return;
    }

    private void displayQuestions() {

        QuestionFactory qf = new QuestionFactory();
        questionHashMap = FastMap.newInstance();

        List<ConfigItem> questions = m_pcw.getQuestions();
        
        if (questions != null) {
            Iterator<ConfigItem> iter = questions.iterator();
            Iterator<XButton> buttons = m_buttonList.iterator();
            while (iter.hasNext()) {
                Question buttonQuestion = qf.get(iter.next());
                XButton button = buttons.next();
                questionHashMap.put(button.getName(), buttonQuestion);
                buttonQuestion.setupButton(button);
                if (buttonQuestion instanceof ListQuestion) {
                    ((ListQuestion)buttonQuestion).setupListPane(m_optionListPane);
                }
                XEventHelper.addMouseHandler(this, button, "buttonPressed");
            }
        }
        return;
    }

    private void getButtons() {
        ArrayList<XButton> buttonList = new ArrayList<XButton>();
        for (String[] buttonSingleArray : buttonArray) {
            for (String buttonName : buttonSingleArray) {
                //Debug.logInfo("ButtonName: "+buttonName, module);
                XButton button = (XButton) m_dialog.findComponent(buttonName);
                buttonList.add(button);
            }
        }
        m_buttonList = buttonList;
    }

//    private void debugQuestions() {
//        //Debug.logInfo("debugQuestions",module);
//        GenericValue gv = m_pcw.getProduct();
//
//        //Debug.logInfo("Product: " +gv.get("description"), module);
//
//        List questions = m_pcw.getQuestions();
//        if (questions==null) return; // no questions, return
//
//        Iterator iter = questions.iterator();
//        while (iter.hasNext()) {
//            ConfigItem question = (ConfigItem)iter.next();
//            /*Debug.logInfo("Question: " + question.getQuestion(), module);
//            Debug.logInfo("IsFirst: "+question.isFirst()+
//                    ", IsMandatory: "+question.isMandatory()+
//                    ", IsSelected: "+question.isSelected()+
//                    ", IsSingleChoice: "+question.isSingleChoice()+
//                    ", IsStandard: "+question.isStandard(), module);*/
//
//            List options = question.getOptions();
//            Iterator itero = options.iterator();
//
//            while (itero.hasNext()) {
//                ConfigOption configoption = (ConfigOption)itero.next();
//                /*Debug.logInfo("Found option " + configoption.getDescription(), module);
//                Debug.logInfo("IsAvailable: "+configoption.isAvailable()+
//                    ", IsSelected: "+configoption.isSelected(), module);*/
//                //configoption.getComponents()
//            }
//        }
//    }

    /*
     *  What are the Question types?
            Must choose one - isMandatory & isSingleChoice
            May choose one - !isMandatory & isSingleChoice
            May choose one or more - !isMandatory & !isSingleChoice
            Must choose one or more - isMandatory & !isSingleChoice
            For !isMandatory, include way to select none

     *  SingleChoice with one option can be a button.  (Can't be mandatory)
    Example: decaf
        SingleChoice with multiple options can be a group of buttons or a list.
                Example: temperature (extra hot, warm, cold)
        Not SingleChoice with multiple options can be a group of buttons or a list
                Example: flavor (vanilla and chocolate)
        Can I specify multiple of an item?  4 shots of espresso?
                Could do as a list?  Example:  Extra shots -> single, double, etc.

        What is isStandard? Maybe I can key off IsStandard for using buttons, others get a list.

        */

    protected class QuestionFactory{

        public Question get(ConfigItem question) {

            List<ConfigOption> options = question.getOptions();
            if (question.isSingleChoice()) {
                if (options.size()>2) {
                   return new ListButtonQuestion(question);
                } else {
                    //TODO: this doesn't handle the case of
                    // two options with none required to be selected
                   return new SingleButtonQuestion(question);
                }
            }
            else{
                return new ListButtonQuestion(question);
            }
        }
    }

    protected interface Question{
        public void setupButton(XButton button);
        //public void setupList(XList list);
        public void buttonClicked();
        public void reset();
    }

    protected interface ListQuestion{
        public void setupListPane(XScrollPane m_optionListPane);
    }

    protected class SingleButtonQuestion implements Question{
        private XButton button = null;
        private ConfigItem question = null;
        private int showOption = 0;

        public SingleButtonQuestion(ConfigItem question) {
            this.question = question;
            return;
        }

        public void setupButton(XButton button) {
            this.button = button;
            List<ConfigOption> options = question.getOptions();
            if (question.isSelected()) {
                ConfigOption selectedOption = question.getSelected();
                showOption = options.indexOf(selectedOption);
            }
            ConfigOption configoption = options.get(showOption);
            button.setText(configoption.getDescription());
            return;
        }

        /*public void setupListPane(XScrollPane m_optionListPane) {
            return;
        } */

        public void buttonClicked() {
            //only two choices, if the button is clicked, toggle
            List<ConfigOption> options = question.getOptions();
            ConfigOption unselectedoption = options.get(showOption);
            unselectedoption.setSelected(false);
            showOption = (showOption+1)%2;
            ConfigOption selectedoption = options.get(showOption);
            selectedoption.setSelected(true);
            button.setText(selectedoption.getDescription());
            return;
        }

        public void reset() {
            showOption = 0;
            List<ConfigOption> options = question.getOptions();
            if (question.isSelected()) {
                ConfigOption selectedOption = question.getSelected();
                showOption = options.indexOf(selectedOption);
            }
            ConfigOption configoption = options.get(showOption);
            button.setText(configoption.getDescription());
            return;
        }
    }

    protected class ListButtonQuestion implements Question, ListQuestion{
        private XButton button = null; // FIXME a bit weird, but I have no time to clean it up...
        private XScrollPane scrollpane = null;
        private ConfigItem question = null;

        public ListButtonQuestion(ConfigItem question) {
            this.question = question;
            return;
        }

        public XButton getButton() {
            return this.button;
        }
        
        public void setupButton(XButton button) {
            this.button = button;
            button.setText(question.getQuestion());
            return;
        }

        public void setupListPane(XScrollPane m_optionListPane) {
            scrollpane = m_optionListPane;
            return;
        }

        public void buttonClicked() {
            DefaultListModel listModel = new DefaultListModel();
            List<ConfigOption> options = question.getOptions();

            for (ConfigOption configoption : options) {
                listModel.addElement(configoption.getDescription());
                //Debug.logInfo("Found option " + configoption.getDescription(), module);
                //Debug.logInfo("IsAvailable: "+configoption.isAvailable()+
                //    ", IsSelected: "+configoption.isSelected(), module);
            }

            //Create the list and put it in a scroll pane.
            JList list = new JList(listModel);
            list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
            LBQSelectionHandler selectionHandler = new LBQSelectionHandler();
            selectionHandler.setQuestion(question);
            list.addListSelectionListener(selectionHandler);

            scrollpane.add(list);
            return;
        }

        public void reset() {
            return;
        }
    }

    protected class LBQSelectionHandler implements ListSelectionListener {
        private ConfigItem question = null;

        public void setQuestion(ConfigItem question) {
            this.question = question;
        }

        public void valueChanged(ListSelectionEvent event) {
            try {
                JList jlist = (JList)event.getSource();
                boolean isAdjusting = event.getValueIsAdjusting();
                if (!isAdjusting) {
                    int[] selected = jlist.getSelectedIndices();
                    //for (int i: selected) {
                    //    Debug.logInfo(""+i, module);
                    //}
                    List<ConfigOption> options = question.getOptions();
                    for (ConfigOption option: options) {
                        option.setSelected(false);
                    }
                    for (int i: selected) {
                        ConfigOption option = options.get(i);
                        option.setSelected(true);
                    }
                    m_configureItem.listPressed();
                }
            }
            catch (Exception ex) {
                Debug.logInfo(ex.getMessage(), module);
                ex.printStackTrace();
            }
        }
    }
}
