package de.hagenah.diplomacy.addins;

import de.hagenah.diplomacy.diptool.*;
import de.hagenah.diplomacy.game.*;
import de.hagenah.diplomacy.map.*;
import de.hagenah.helper.*;
import java.util.*;
import javax.swing.*;

/**
 * This add-in calculates a simple opening statistic.
 */
public class StatAddIn
{
    /**
     * Each time the add-in is called a new object is created. This constructor
     * should not return before the add-in has finished. It is executed by the
     * event dispatching thread.
     *
     * @param parent
     *   A parent frame for dialog boxes
     * @param preferences
     *   The preferences of the user
     * @param obj
     *   The selected object in the tree:
     *   <ul>
     *   <li>a DipTurn, or</li>
     *   <li>a DipGame, or</li>
     *   <li>a DipGameGroup, or</li>
     *   <li>a Map (String &rarr; DipGameGroup).</li>
     *   </ul>
     */
    public StatAddIn(JFrame parent,Preferences preferences,Object obj)
    {
        StringBuffer buffer;
        Iterator i,j;
        List games;
        int season;
        Map.Entry countryopenings,opening;
        Map[] openings;

        // The openings (Country &rarr; Map (String - opening &rarr; List (String - game name))).
        openings=new Map[]
        {
            new TreeMap(),
            new TreeMap()
        };
        // Add all games to openings
        for(season=0;season<2;season++)
        {
            if(obj instanceof DipGame)
                addGame((DipGame)obj,openings[season],season+Turn.NUMBER_FIRST);
            else if(obj instanceof DipGameGroup)
            {
                j=((DipGameGroup)obj).getGames().iterator();
                while(j.hasNext())
                    addGame((Game)j.next(),openings[season],season+Turn.NUMBER_FIRST);
            }
            else if(obj instanceof Map)
            {
                i=((Map)obj).values().iterator();
                while(i.hasNext())
                {
                    j=((GameGroup)i.next()).getGames().iterator();
                    while(j.hasNext())
                        addGame((Game)j.next(),openings[season],season+Turn.NUMBER_FIRST);
                }
            }
            else
                throw new IllegalArgumentException("Type must not be 'Turn'");
        }
        // Show openings
        buffer=new StringBuffer();
        for(season=0;season<2;season++)
        {
            if(season==0)
                buffer.append("Spring\n======\n\n");
            else
                buffer.append("Fall\n====\n\n");
            i=openings[season].entrySet().iterator();
            while(i.hasNext())
            {
                countryopenings=(Map.Entry)i.next();
                buffer.append(countryopenings.getKey().toString());
                buffer.append(":\n");
                j=((Map)countryopenings.getValue()).entrySet().iterator();
                while(j.hasNext())
                {
                    opening=(Map.Entry)j.next();
                    games=(List)opening.getValue();
                    buffer.append(games.size());
                    buffer.append(" * ");
                    buffer.append((String)opening.getKey());
                    buffer.append("  ");
                    buffer.append(games.toString());
                    buffer.append("\n");
                }
                buffer.append("\n");
            }
        }
        if(buffer.length()>0)
            buffer.setLength(buffer.length()-"\n\n".length());
        SwingHelper.showMessageDialog(parent,"Openings:",buffer.toString(),"DipTool Stat Add-In",JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * Adds the openings of a game.
     *
     * @param game
     *   The game
     * @param openings
     *   The openings (Country &rarr; Map (String - opening &rarr; List (String - game name))).
     * @param turnnumber
     *   The number of the turn
     */
    private void addGame(Game game,Map openings,int turnnumber)
    {
        Country country;
        Map countryopenings;
        Order order;
        Turn turn;
        StringBuffer buffer;
        String text;
        List games;
        Iterator i,j;

        turn=game.getTurn(turnnumber);
        if(turn!=null && turn.areOrdersKnown())
        {
            // Iterate over all countries
            i=game.getMap().getCountries().iterator();
            while(i.hasNext())
            {
                country=(Country)i.next();
                // Concatenate orders of country
                buffer=new StringBuffer();
                j=turn.getOrders().iterator();
                while(j.hasNext())
                {
                    order=(Order)j.next();
                    if(order.getCountry()==country)
                    {
                        buffer.append(order.toString(Order.TOSTRING_RESULT+Order.TOSTRING_SHORT,turn.getUnits()));
                        buffer.append(", ");
                    }
                }
                if(buffer.length()>0)
                {
                    buffer.setLength(buffer.length()-", ".length());
                    // Retrieve countyopenings
                    countryopenings=(Map)openings.get(country);
                    if(countryopenings==null)
                    {
                        countryopenings=new TreeMap();
                        openings.put(country,countryopenings);
                    }
                    // Retrieve games list
                    text=buffer.toString();
                    games=(List)countryopenings.get(text);
                    if(games==null)
                    {
                        games=new ArrayList();
                        countryopenings.put(text,games);
                    }
                    // Add game to opening
                    games.add(game.getName());
                }
            }
        }
    }
}
