/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : HostSelectorList.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */
package ciss.phase_viewer.ssh.hosts;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;

public class HostSelectorList extends JPanel implements HostSelector {
    private static Logger logger = Logger.getLogger(HostSelectorList.class
            .getName());

    private JList jList;

    private HostList list;

    public HostSelectorList() {
        super();
        init();
    }

    public JList getJList() {
        return this.jList;
    }

    private void init() {
        try {
            jList = new JList();

            jList.getSelectionModel().setSelectionMode(
                    ListSelectionModel.SINGLE_SELECTION);
            setLayout(new GridLayout());

            list = HostList.getHostList();
            int numHosts = list.size();

            add(jList);
            // add(new CBPanel(numHosts));
            // setCellRenderer(new CheckListRenderer());
            String[] infos = new String[numHosts];
            // DefaultListModel model = new DefaultListModel();
            for (int i = 0; i < numHosts; i++) {
                // model.addElement(new CheckableItem(list.getHostInfo(i)
                // .getName()));
                infos[i] = list.getHostInfo(i).getName();
            }
            // super.setModel(model);
            jList.setListData(infos);
            revalidate();
        } catch (Exception exc) {
            exc.printStackTrace();
        }

    }

    public HostInfo getSelectedHost() {
        return list.getHostInfo(getSelectedIndex());
    }

    public HostList getListofHosts() {
        return this.list;
    }

    public int getSelectedIndex() {
        return jList.getSelectedIndex();
    }

    class CheckableItem {
        private String str;

        private boolean isSelected;

        public CheckableItem(String str) {
            this.str = str;
            isSelected = false;
        }

        public void setSelected(boolean b) {
            isSelected = b;
        }

        public boolean isSelected() {
            return isSelected;
        }

        public String toString() {
            return str;
        }
    }

    class CheckListRenderer extends JCheckBox implements ListCellRenderer {

        public CheckListRenderer() {
            setBackground(UIManager.getColor("List.textBackground"));
            setForeground(UIManager.getColor("List.textForeground"));
        }

        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean hasFocus) {
            setEnabled(list.isEnabled());
            setSelected(((CheckableItem) value).isSelected());
            setFont(list.getFont());
            setText(value.toString());
            return this;
        }
    }

    class CBPanel extends JPanel {
        CBPanel(int numhosts) {
            setLayout(new GridLayout(numhosts, 1));
            for (int i = 0; i < numhosts; i++)
                add(new JCheckBox(""));
        }
    }

    public void addHost(HostInfo hostInfo) {
        // TODO Auto-generated method stub
        list.add(hostInfo);
        ((DefaultListModel) jList.getModel()).addElement(hostInfo);
    }

    public void deleteSelectedHost() {
        // TODO Auto-generated method stub
        int ind = jList.getSelectedIndex();
        list.remove(ind);
        ((DefaultListModel) jList.getModel()).remove(ind);
    }
}

class CheckBoxJList extends JList implements ListSelectionListener,
        MouseMotionListener {

    static Color listForeground, listBackground, listSelectionForeground,
            listSelectionBackground;
    static {
        UIDefaults uid = UIManager.getLookAndFeel().getDefaults();
        listForeground = uid.getColor("List.foreground");
        listBackground = uid.getColor("List.background");
        listSelectionForeground = uid.getColor("List.selectionForeground");
        listSelectionBackground = uid.getColor("List.selectionBackground");
    }

    HashSet selectionCache = new HashSet();

    int toggleIndex = -1;

    boolean toggleWasSelected;

    public CheckBoxJList() {
        super();
        addMouseMotionListener(this);
        setCellRenderer(new CheckBoxListCellRenderer());
        addListSelectionListener(this);
    }

    // ListSelectionListener implementation
    public void valueChanged(ListSelectionEvent lse) {
        // System.out.println(lse);
        if (!lse.getValueIsAdjusting()) {
            removeListSelectionListener(this);

            // remember everything selected as a result of this action
            HashSet newSelections = new HashSet();
            int size = getModel().getSize();
            for (int i = 0; i < size; i++) {
                if (getSelectionModel().isSelectedIndex(i)) {
                    newSelections.add(new Integer(i));
                }
            }

            // turn on everything that was previously selected
            Iterator it = selectionCache.iterator();
            while (it.hasNext()) {
                int index = ((Integer) it.next()).intValue();
                // System.out.println("adding " + index);
                getSelectionModel().addSelectionInterval(index, index);
            }

            // add or remove the delta
            it = newSelections.iterator();
            while (it.hasNext()) {
                Integer nextInt = (Integer) it.next();
                int index = nextInt.intValue();
                if (selectionCache.contains(nextInt))
                    getSelectionModel().removeSelectionInterval(index, index);
                else
                    getSelectionModel().addSelectionInterval(index, index);
            }

            // save selections for next time
            selectionCache.clear();
            for (int i = 0; i < size; i++) {
                if (getSelectionModel().isSelectedIndex(i)) {
                    // System.out.println("caching " + i);
                    selectionCache.add(new Integer(i));
                }
            }

            addListSelectionListener(this);

        }
    }

    public static void main(String[] args) {
        JList list = new CheckBoxJList();
        DefaultListModel defModel = new DefaultListModel();
        list.setModel(defModel);
        String[] listItems = { "Chris", "Joshua", "Daniel", "Michael", "Don",
                "Kimi", "Kelly", "Keagan" };
        Iterator it = Arrays.asList(listItems).iterator();
        while (it.hasNext())
            defModel.addElement(it.next());
        // show list
        JScrollPane scroller = new JScrollPane(list,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        JFrame frame = new JFrame("Checkbox JList");
        frame.getContentPane().add(scroller);
        frame.pack();
        frame.setVisible(true);
    }

    private boolean checkCheckBox(int offx) {
        System.out.println("size: " + offx + ",currx: " + currx);
        if (currx > 0 && currx < offx)
            return true;
        return false;
    }

    class CheckBoxListCellRenderer extends JComponent implements
            ListCellRenderer {
        DefaultListCellRenderer defaultComp;

        JCheckBox checkbox;

        public CheckBoxListCellRenderer() {
            setLayout(new BorderLayout());
            defaultComp = new DefaultListCellRenderer();
            checkbox = new JCheckBox();
            add(checkbox, BorderLayout.WEST);
            add(defaultComp, BorderLayout.CENTER);
        }

        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            defaultComp.getListCellRendererComponent(list, value, index,
                    isSelected, cellHasFocus);
            /*
             * checkbox.setSelected (isSelected); checkbox.setForeground
             * (isSelected ? listSelectionForeground : listForeground);
             * checkbox.setBackground (isSelected ? listSelectionBackground :
             * listBackground);
             */
            // checkbox.setSelected(isSelected);
            try {
                int cx = getLocation().x;
                int cy = getLocation().y;
                int offx = (int) checkbox.getSize().getWidth();
                int offy = (int) checkbox.getSize().getHeight();
                if (checkCheckBox(offx))
                    checkbox.setSelected(isSelected);
            } catch (Exception exc) {
                exc.printStackTrace();
            }

            Component[] comps = getComponents();
            for (int i = 0; i < comps.length; i++) {
                comps[i].setForeground(listForeground);
                comps[i].setBackground(listBackground);
            }
            return this;
        }

    }

    private int currx = 0;
    private int curry = 0;

    public void mouseDragged(MouseEvent arg0) {
        // TODO Auto-generated method stub
        this.currx = arg0.getPoint().x;
        this.curry = arg0.getPoint().y;
    }

    public void mouseMoved(MouseEvent arg0) {
        // TODO Auto-generated method stub
        this.currx = arg0.getPoint().x;
        this.curry = arg0.getPoint().y;
    }

}
