/* MindgameComponent.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.BorderLayout;
import java.awt.Container;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.SwingConstants;
import org.grinvin.gui.components.MindgameButtonsComponent.MindgameButtonsComponentListener;
import org.grinvin.gui.icons.SvgIconManager;
import org.grinvin.list.graphs.GraphListElement;
import org.grinvin.list.graphs.GraphListElementManager;

/**
 *
 */
public class MindgameComponent extends JPanel implements MindgameButtonsComponentListener {

    //
    private static final String BUNDLE_NAME = "org.grinvin.main.resources";
    
    //
    private final String[] CHOICES = {
        "graph:org.grinvin.factories.CompleteGraphFactory?order=3",
        "graph:org.grinvin.factories.CompleteGraphFactory?order=5",
        "graph:org.grinvin.factories.CompleteGraphFactory?order=7",
        "graph:org.grinvin.factories.PathFactory?order=2",
        "graph:org.grinvin.factories.PathFactory?order=3",
        "graph:org.grinvin.factories.PathFactory?order=4",
        "graph:org.grinvin.factories.BipartiteFactory?order1=2&order2=2",
        "graph:org.grinvin.factories.BipartiteFactory?order1=3&order2=2",
        "graph:org.grinvin.factories.BipartiteFactory?order1=2&order2=3",
        "graph:org.grinvin.factories.StarGraphFactory?order=4",
        "graph:org.grinvin.factories.StarGraphFactory?order=5",
        "graph:org.grinvin.factories.StarGraphFactory?order=6"
    };
    
    private final int[][] LEVELS = {
        {0, 3},
        {0, 3, 6},
        {0, 3, 6, 9},
        {0, 2, 3, 5, 8, 11},
        {0, 2, 3, 5, 6, 8, 9, 11},
        {0, 1, 2, 3, 4, 5, 9, 10, 11},
        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
    };
    
    //
    private MindgameButtonsComponent buttonsComponent;
    
    //
    private JLabel timeLabel;
    
    //
    private JLabel errorLabel;
    
    //
    private Date startTime;
    
    //
    private boolean finished;

    //
    private final Icon BACK_ICON = SvgIconManager.getInstance().getIcon("/org/grinvin/icons/grinvin.svg", 60);
    
    private int level = 0;
    
    //
    public MindgameComponent() {
        setLayout(new BorderLayout());
        nextLevel();
        Container topComponent = new JPanel();
        topComponent.setLayout(new BorderLayout());

        timeLabel = new JLabel("00:00:00", SwingConstants.RIGHT);
        topComponent.add(timeLabel, BorderLayout.EAST);
        errorLabel = new JLabel(ResourceBundle.getBundle(BUNDLE_NAME).getString("mindgame.errors") + buttonsComponent.getErrors());
        topComponent.add(errorLabel, BorderLayout.WEST);
        
        add(topComponent, BorderLayout.NORTH);

        startTime = Calendar.getInstance().getTime();
        finished = false;
        new Thread(new Runnable() {
            public void run() {
                while(!finished) {
                    long time1 = startTime.getTime();
                    long time2 = Calendar.getInstance().getTime().getTime();
                    long difference = Math.abs(time2 - time1);
                    timeLabel.setText(formatTime(difference / 1000));
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        // ignore
                    }
                }
            }
        }).start();
    }

    public String formatTime(long totalSeconds) {
        long hours = totalSeconds / 3600;
        totalSeconds = totalSeconds - (hours * 3600);
        long minutes = totalSeconds / 60;
        totalSeconds = totalSeconds - (minutes * 60);
        return (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ":" + (totalSeconds < 10 ? "0" : "") + totalSeconds;
    }

    //
    private Icon getIcon(String file) {
        try {
            GraphListElement element = GraphListElementManager.getInstance().getGraphListElement(new URI(file));
            Icon icon = element.getBundle().getGraphIconFactory().createIcon(element.getBundle(), 60);
            return icon;
        } catch (URISyntaxException ex) {
            return null;
        }
    }
    
    private Icon[] getIcons(int level) {
        Icon[] icons = new Icon[LEVELS[level].length];
        for(int i=0; i < LEVELS[level].length; i++)
            icons[i] = getIcon(CHOICES[LEVELS[level][i]]);
        return icons;
    }
    
    public void nextLevel() {
        if (buttonsComponent != null)
            remove(buttonsComponent);
        if (level < LEVELS.length) {
            buttonsComponent = new MindgameButtonsComponent(getIcons(level), BACK_ICON);
            buttonsComponent.setListener(this);
            add(buttonsComponent, BorderLayout.CENTER);
            level++;
            setSize(getPreferredSize());
        } else {
            finished = true;
            buttonsComponent = null;
            JLabel label = new JLabel(ResourceBundle.getBundle(BUNDLE_NAME).getString("mindgame.finished"), SwingConstants.CENTER);
            add(label, BorderLayout.CENTER);
        }
        revalidate();
        repaint();
    }
    
    Runnable doNextLevel = new Runnable() {
        public void run() {
            nextLevel();
        }
    };
    
    public void allDone() {
        nextLevel();
        //SwingUtilities.invokeLater(doNextLevel);
    }
    
    public void madeError() {
        errorLabel.setText(ResourceBundle.getBundle(BUNDLE_NAME).getString("mindgame.errors") + buttonsComponent.getErrors());
    }
    
}