/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package worldserver3d.view;

import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Observable;
import javax.swing.*;
import model.Environment;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Observer;
import java.util.TreeSet;
import model.Creature;
import model.Leaflet;
import util.Constants;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author eccastro
 */
public class KnapsackAndScoreFrame extends JFrame implements Observer {

    JPanel mainmainPanel;
    JPanel mainPanel;
    JPanel panel1;
    JPanel panel1_1;
    JPanel panel1_2;
    JPanel panel2;
    JPanel panel3;
    JPanel panel_2_3;
    JPanel panelButtons;
    JPanel panelEnergy;
    JButton closeButton;
    JButton refillButton;
    JButton stopButton;
    List<JLabel> labelPool;
    List<JTextField> textPool;
    List<JTextField> textPoolLeaflet;
    JLabel scoreLabel;
    JTextField scoreTF;
    JLabel pFoodLabel;
    JLabel npFoodLabel;
    JTextField pFoodTF;
    JTextField npFoodTF;
    private Environment e;
    public Creature creature;
    JTextField greenTxt;
    JTextField redTxt;
    JTextField blueTxt;
    JTextField yellowTxt;
    JTextField whiteTxt;
    JTextField magentaTxt;
    JPanel leafletTypesPanel = new JPanel();
    HashMap<Long, List<JTextField>> leafletsTextFields = new HashMap<Long, List<JTextField>>();
    JTextArea ta;
    JProgressBar energyBar = new JProgressBar(0, (int) Constants.CREATURE_MAX_FUEL);

    public KnapsackAndScoreFrame() throws InvocationTargetException {
        this.creature = null;
        try {
            SwingUtilities.invokeAndWait(new Runnable() {

                public void run() {
                    createSwingStuff();
                }
            });
        } catch (InterruptedException ie) {
            return;
        } catch (InvocationTargetException ite) {
            throw new RuntimeException(ite);
        }
//        SwingUtilities.invokeLater(new Runnable() {
//
//            public void run() {
//                createSwingStuff();
//            }
//        });
//
    }

    public void update() {
        if (this.creature != null) {
            refreshKnapsackScoreData();
            reBuildLeafletPanel();
        }
    }

    private JPanel createJewelsKnapsack(String[] array) {


        JPanel typesPanel = new JPanel();
        typesPanel.setLayout(new GridLayout(6, 2));
        labelPool = new ArrayList<JLabel>();
        textPool = new ArrayList<JTextField>();

        JLabel color0Label = new JLabel(array[0]);
        JLabel color1Label = new JLabel(array[1]);
        JLabel color2Label = new JLabel(array[2]);
        JLabel color3Label = new JLabel(array[3]);
        JLabel color4Label = new JLabel(array[4]);
        JLabel color5Label = new JLabel(array[5]);
        labelPool.add(color0Label);
        labelPool.add(color1Label);
        labelPool.add(color2Label);
        labelPool.add(color3Label);
        labelPool.add(color4Label);
        labelPool.add(color5Label);

        greenTxt = new JTextField("0", 4);
        redTxt = new JTextField("0", 4);
        blueTxt = new JTextField("0", 4);
        yellowTxt = new JTextField("0", 4);
        whiteTxt = new JTextField("0", 4);
        magentaTxt = new JTextField("0", 4);

        greenTxt.setEditable(false);
        redTxt.setEditable(false);
        blueTxt.setEditable(false);
        yellowTxt.setEditable(false);
        whiteTxt.setEditable(false);
        magentaTxt.setEditable(false);

        textPool.add(redTxt);
        textPool.add(greenTxt);
        textPool.add(blueTxt);
        textPool.add(yellowTxt);
        textPool.add(magentaTxt);
        textPool.add(whiteTxt);

        typesPanel.add(color0Label);
        typesPanel.add(redTxt);
        typesPanel.add(color1Label);
        typesPanel.add(greenTxt);
        typesPanel.add(color2Label);
        typesPanel.add(blueTxt);
        typesPanel.add(color3Label);
        typesPanel.add(yellowTxt);
        typesPanel.add(color4Label);
        typesPanel.add(magentaTxt);
        typesPanel.add(color5Label);
        typesPanel.add(whiteTxt);
        return typesPanel;

    }

    private void updateLeafletFields() {

        TreeSet tree = new TreeSet();
        for (Leaflet l : e.getLeafletsOfOwner(creature.getID())) {
            tree.add(l.getID());
        }
        resetLeaflet();
        for (int i = 0; i <= Constants.MAX_NUMBER_OF_COLORS - 1; i++) {
            for (int j = 0; j <= Constants.MAX_NUMBER_OF_LEAFLETS - 1; j++) {
                Object[] array = tree.toArray();
                Leaflet l = (Leaflet) e.getLeafletPool().get((Long) array[j]);

                String str = l.getNumberOfJewels(Constants.getColorItem(i)).toString();
                ((JTextField) leafletTypesPanel.getComponent(i * 3 + j)).setText(str);

            }
        }
        repaint();
    }

    private void addLeafletTextFields(Long leafletID) {
        List<JTextField> leafletTextFieldList = new ArrayList();
        JTextField greenTxtLeaflet = new JTextField("0", 3);
        JTextField redTxtLeaflet = new JTextField("0", 3);
        JTextField blueTxtLeaflet = new JTextField("0", 3);
        JTextField yellowTxtLeaflet = new JTextField("0", 3);
        JTextField whiteTxtLeaflet = new JTextField("0", 3);
        JTextField magentaTxtLeaflet = new JTextField("0", 3);

        greenTxtLeaflet.setEditable(false);
        redTxtLeaflet.setEditable(false);
        blueTxtLeaflet.setEditable(false);
        yellowTxtLeaflet.setEditable(false);
        whiteTxtLeaflet.setEditable(false);
        magentaTxtLeaflet.setEditable(false);

        leafletTextFieldList.add(redTxtLeaflet);
        leafletTextFieldList.add(greenTxtLeaflet);
        leafletTextFieldList.add(blueTxtLeaflet);
        leafletTextFieldList.add(yellowTxtLeaflet);
        leafletTextFieldList.add(whiteTxtLeaflet);
        leafletTextFieldList.add(magentaTxtLeaflet);

        leafletsTextFields.put(leafletID, leafletTextFieldList);
    }

    private void initBuildLeafletsTextFields(JPanel panel) {

        for (int i = 0; i <= Constants.MAX_NUMBER_OF_LEAFLETS - 1; i++) {
            addLeafletTextFields(new Long(i));
        }

    }

    private void loadLeafletsTextFields(JPanel typesPanel) {
        typesPanel.removeAll();
        for (int i = 0; i <= Constants.MAX_NUMBER_OF_COLORS - 1; i++) {
            for (Iterator<Long> iter = leafletsTextFields.keySet().iterator(); iter.hasNext();) {
                Long ID = iter.next();
                typesPanel.add(leafletsTextFields.get(ID).get(i));
            }
        }

    }

    private JPanel createLeafletJewels() {

        leafletTypesPanel.setLayout(new GridLayout(6, Constants.MAX_NUMBER_OF_LEAFLETS));

        initBuildLeafletsTextFields(leafletTypesPanel);
        loadLeafletsTextFields(leafletTypesPanel);

        return leafletTypesPanel;

    }

    public void setCreature(Creature c) {
        if (this.creature != null) {
            this.creature.sack.deleteObserver(this);
        }
        this.creature = c;
        ta.setText("                       "+this.creature.getMyName());
        this.creature.sack.addObserver(this);
        this.creature.fuelNotifier.addAnObserver(this);
        this.creature.leafletNotifier.addAnObserver(this);
        refreshEnergyData();

    }

    public void setEnvironment(Environment env) {
        e = env;
        e.leafletNotifier.addAnObserver(this);
    }

    public void refreshKnapsackScoreData() {

        scoreTF.setText(new Integer(this.creature.sack.score).toString());
        greenTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorGREEN)).toString());
        redTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorRED)).toString());
        blueTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorBLUE)).toString());
        yellowTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorYELLOW)).toString());
        magentaTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorMAGENTA)).toString());
        whiteTxt.setText((this.creature.sack.getNumberOfJewels(Constants.colorWHITE)).toString());

        pFoodTF.setText((this.creature.sack.getNumberOfFood(Constants.PFOOD)).toString());
        npFoodTF.setText((this.creature.sack.getNumberOfFood(Constants.NPFOOD)).toString());

    }

    public void refreshEnergyData() {
        System.out.println("---------------refreshEnergyData---------------");

        if (this.creature.getFuel() >= (0.5 * Constants.CREATURE_MAX_FUEL)) {
            energyBar.setForeground(Color.GREEN);
        } else if ((this.creature.getFuel() < (0.5 * Constants.CREATURE_MAX_FUEL)) && (this.creature.getFuel() >= (0.25 * Constants.CREATURE_MAX_FUEL))) {
            energyBar.setForeground(Color.YELLOW);
        } else {
            energyBar.setForeground(Color.RED);
        }
        energyBar.setValue(this.creature.getFuel());
    }

    private void reBuildLeafletPanel() {

        if ((e != null) && (!e.getLeafletPool().isEmpty())) {
            updateLeafletFields();

        }
    }

    private void updateLeafletActivity(Long leafletID) {

        TreeSet tree = new TreeSet();
        for (Leaflet l : e.getLeafletsOfOwner(creature.getID())) {
            tree.add(l.getID());
        }
        resetLeaflet();
        for (int i = 0; i <= Constants.MAX_NUMBER_OF_COLORS - 1; i++) {
            for (int j = 0; j <= Constants.MAX_NUMBER_OF_LEAFLETS - 1; j++) {
                Object[] array = tree.toArray();
                Leaflet l = (Leaflet) e.getLeafletPool().get((Long) array[j]);
                if(l.getActivity() == 1) ((JTextField) leafletTypesPanel.getComponent(i * 3 + j)).setEnabled(true);
                else ((JTextField) leafletTypesPanel.getComponent(i * 3 + j)).setEnabled(false);
            }
        }
        repaint();

    }

    private void resetLeaflet() {

        for (int i = 0; i <= Constants.MAX_NUMBER_OF_LEAFLETS * Constants.LEAFLET_ITEMS_NUMBER; i++) {
            ((JTextField) leafletTypesPanel.getComponent(i)).setText((new Integer(0)).toString());
        }
        System.out.println("Leaflet was reset.");


    }

    private void createSwingStuff() {
        mainmainPanel = new JPanel();
        mainPanel = new JPanel();
        panel1 = new JPanel();
        panel1_1 = new JPanel();
        panel1_2 = new JPanel();
        panel2 = new JPanel();
        panel3 = new JPanel();
        panel_2_3 = new JPanel();
        panelButtons = new JPanel();
        panelEnergy = new JPanel();
        ta = new JTextArea("");
        ta.setEditable(false);

        closeButton = new JButton("Close");
        stopButton = new JButton("Start/Stop");
        refillButton = new JButton("Refill");
        closeButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });

        stopButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if(creature.hasStarted){
                    creature.hasStarted = false;
                    stopButton.setText("Start");
                    
                }else{
                    creature.hasStarted = true;
                    stopButton.setText("Stop");
                }
                
            }
        });
        refillButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ev) {
                System.out.println("*** Refill ***");
                refill();
                repaint();

            }
        });
        panel1_1.setBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Knapsack:"),
                BorderFactory.createEmptyBorder(3, 3, 3, 3)),
                panel1.getBorder()));
        panel1_2.setBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Leaflets:"),
                BorderFactory.createEmptyBorder(3, 3, 3, 6)),
                panel1.getBorder()));

        panel1.setLayout(new GridBagLayout());
        GridBagConstraints gm1 = new GridBagConstraints();
        gm1.fill = GridBagConstraints.VERTICAL;
        gm1.gridx = 0;
        gm1.gridy = 0;

        panel1_1.add(createJewelsKnapsack(Constants.arrayOfColors));
        panel1_2.add(createLeafletJewels());

        panel1.add(panel1_1);

        gm1.gridx = 0;
        gm1.gridy = 1;
        panel1.add(panel1_2);

        mainmainPanel.setLayout(new BorderLayout());

        mainPanel.setLayout(new GridBagLayout());
        GridBagConstraints gm = new GridBagConstraints();
        gm.anchor = GridBagConstraints.FIRST_LINE_START;
        mainPanel.add(panel1, gm);

        panel_2_3.setLayout(new GridLayout(2, 1));

        panel2.setBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Score:"),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)),
                panel2.getBorder()));
        panel2.setLayout(new GridBagLayout());
        GridBagConstraints grid = new GridBagConstraints();
        grid.fill = GridBagConstraints.HORIZONTAL;
        grid.gridx = 0;
        grid.gridy = 0;
        grid.weightx = 0.5;
        scoreLabel = new JLabel("Score: ");
        panel2.add(scoreLabel, grid);
        scoreTF = new JTextField("0", 4);
        scoreTF.setEditable(false);
        grid.gridx = 1;
        panel2.add(scoreTF, grid);

        panel_2_3.add(panel2);

        panel3.setBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Food:"),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)),
                panel3.getBorder()));
        panel3.setLayout(new GridBagLayout());
        grid.fill = GridBagConstraints.VERTICAL;
        grid.gridx = 0;
        grid.gridy = 0;
        grid.weightx = 0.5;
        pFoodLabel = new JLabel("PFood: ");
        panel3.add(pFoodLabel, grid);
        grid.gridy = 1;
        npFoodLabel = new JLabel("NPFood: ");
        panel3.add(npFoodLabel, grid);
        grid.gridx = 1;
        grid.gridy = 0;
        pFoodTF = new JTextField("0", 4);
        pFoodTF.setEditable(false);
        panel3.add(pFoodTF, grid);

        grid.gridx = 1;
        grid.gridy = 1;
        npFoodTF = new JTextField("0", 4);
        npFoodTF.setEditable(false);
        panel3.add(npFoodTF, grid);

        panel_2_3.add(panel3);


        gm.anchor = GridBagConstraints.FIRST_LINE_END;
        mainPanel.add(panel_2_3, gm);

//
        GridLayout gd = new GridLayout(1, 2);
        gd.setHgap(20);
        panelButtons.setLayout(gd);

        panelButtons.add(refillButton);
        refillButton.setVisible(true);
        panelButtons.add(stopButton);
        stopButton.setVisible(true);
        panelButtons.add(closeButton);

        panelEnergy.setBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Energy:"),
                BorderFactory.createEmptyBorder(2, 2, 2, 2)),
                panelEnergy.getBorder()));
        panelEnergy.setLayout(new GridLayout(1, 1));
        energyBar.setStringPainted(true);
        panelEnergy.add(energyBar);

        gm.fill = GridBagConstraints.BOTH;

        gm.gridy = 1;
        gm.gridwidth = GridBagConstraints.REMAINDER;
        mainPanel.add(panelEnergy, gm);
        gm.gridy = 2;
        mainPanel.add(panelButtons, gm);

        mainmainPanel.add(ta, BorderLayout.PAGE_START);
        mainmainPanel.add(mainPanel, BorderLayout.PAGE_END);
        add(mainmainPanel);
        pack();
        setVisible(false);
        setResizable(false);
    }

    private void refill() {
        if (this.creature != null) {
            this.creature.refill();
        }
    }

    public void update(Observable o, Object obj) {

        if (obj != null) {
            if ((Long) obj == 0) {
                refreshKnapsackScoreData();
            } else if ((Long) obj == 1) {
                reBuildLeafletPanel();
            } else {
                updateLeafletActivity((Long) obj);
            }

        } else {
            refreshEnergyData();
        }

    }
}

