/* MindgameButtonsComponent.java
 * =========================================================================
 * This file is part of the GrInvIn project - http://www.grinvin.org
 * 
 * Copyright (C) 2005-2008 Universiteit Gent
 * 
 * This program 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.
 * 
 * This program 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.
 * 
 * A copy of the GNU General Public License can be found in the file
 * LICENSE.txt provided with the source distribution of this program (see
 * the META-INF directory in the source jar). This license can also be
 * found on the GNU website at http://www.gnu.org/licenses/gpl.html.
 * 
 * If you did not receive a copy of the GNU General Public License along
 * with this program, contact the lead developer, or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package org.grinvin.gui.components;

import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.Timer;

import org.grinvin.graphs.GraphURIType;

/**
 *
 */
public class MindgameButtonsComponent extends JPanel {
    
    //
    private JToggleButton[] toggleButtons;
    
    //
    private JToggleButton first;
    
    //
    private JToggleButton second;

    //
    private Timer timer;
    
    //
    private int errors = 0;

    public int getErrors() {
        return errors;
    }
    

    /** Creates a new instance of MindgameButtonsComponent */
    public MindgameButtonsComponent(Icon[] icons, Icon backIcon) {
        timer = new Timer(2000, new TimerListener());
        first = null;
        setLayout(getLayoutManager(icons.length));
        initButtons(icons, backIcon);
    }
    
    private LayoutManager getLayoutManager(int iconcount) {
        return new GridLayout(bestDivisor(iconcount*2), 0);
    }
    
    // find the best square
    private int bestDivisor(int number) {
        int i = (int)Math.sqrt(number);
        while (i > 1 && (number % i) != 0)
            i--;
        return i;
    }
    
    //
    private static final Insets EMPTY_MARGIN = new Insets(0,0,0,0);
    
    private void initButtons(Icon[] icons, Icon backIcon) {
        
        int [] positions = randomPositions(icons.length);
        
        ButtonListener buttonListener = new ButtonListener();
        
        toggleButtons = new JToggleButton[positions.length];
        for (int i=0;i<toggleButtons.length;i++) {
            toggleButtons[i] = new JToggleButton(backIcon);
            toggleButtons[i].setSelectedIcon(backIcon);
            toggleButtons[i].setDisabledSelectedIcon(icons[positions[i]]);
            toggleButtons[i].setDisabledIcon(backIcon);
            toggleButtons[i].addActionListener(buttonListener);
            toggleButtons[i].setMargin(EMPTY_MARGIN);
            add(toggleButtons[i]);
        }
    }

    //
    private static final Random RG = new Random();
    
    //
    private int [] randomPositions(int iconcount){
        int[] positions = new int[2 * iconcount];
        for (int i=0; i< positions.length; i++) {
            positions[i] = i/2;
        }
        
        // willekeurige herschikking
        for (int i=positions.length-1; i >= 1; i--) {
            int j = RG.nextInt(i+1);
            if (i != j) {
                int p = positions[i];
                positions[i] = positions[j];
                positions[j] = p;
            }
        }
        return positions;
    }
    
    private MindgameButtonsComponentListener listener;
    
    public interface MindgameButtonsComponentListener {
        public void allDone();
        public void madeError();
    }
    
    public void setListener(MindgameButtonsComponentListener listener) {
        this.listener = listener;
    }
    
    //
    private class TimerListener implements ActionListener {
        
        /**
         * Keert de getoonde kaarten terug om.
         */
        public void actionPerformed(ActionEvent e) {
            
            first.setSelected(false);
            second.setSelected(false);
            first.setBackground(null);
            second.setBackground(null);
            // maak 'kaart'-knoppen terug actief
            for (JToggleButton button : toggleButtons)
                if (!button.isSelected())
                    button.setEnabled(true);
            first = null;
            timer.stop();
        }
        
    }
    
    //
    private class ButtonListener implements ActionListener {
        
        /**
         * Reageer op het kiezen van een kaart.
         */
        public void actionPerformed(ActionEvent e) {
            if (first == null) {
                // Kies de eerste kaart
                first = (JToggleButton) e.getSource();
                first.setEnabled(false);
                first.setBackground(GraphURIType.GRAPH_GLOBAL.getIconBackgroundColor());
                repaint();
            } else {
                // Kies de tweede kaart
                second = (JToggleButton) e.getSource();
                second.setEnabled(false);
                second.setBackground(GraphURIType.GRAPH_GLOBAL.getIconBackgroundColor());
                if(!first.getDisabledSelectedIcon().equals(second.getDisabledSelectedIcon())) {
                    errors++;
                    listener.madeError();
                    for (JToggleButton button : toggleButtons)
                        button.setEnabled(false);
                    timer.start();
                } else {
                    first = null;
                    second = null;
                    //check if finished
                    boolean finished = true;
                    for (JToggleButton button : toggleButtons)
                        if (!button.isSelected())
                            finished = false;
                    if (finished)
                        listener.allDone();
                }
            }
        }
        
    }

    
}
