package net.sf.colossus.client;


import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

import net.sf.colossus.server.Constants;
import net.sf.colossus.util.KDialog;


/**
 * Negotiate allows making a new proposal to settle an engagement.
 * @version $Id: Negotiate.java,v 1.15 2004/01/22 01:26:40 dripton Exp $
 * @author David Ripton
 */

final class Negotiate extends KDialog implements MouseListener, ActionListener
{
    private String attackerId;
    private String defenderId;
    private List attackerChits = new ArrayList();
    private List defenderChits = new ArrayList();
    private Client client;
    private Proposal proposal;
    private Point location;
    private SaveWindow saveWindow;

    Negotiate(Client client, String attackerId, String defenderId)
    {
        super(client.getBoard().getFrame(), client.getPlayerName() + ": " +
                attackerId + " Negotiates with " + defenderId, false);

        this.client = client;
        this.attackerId = attackerId;
        this.defenderId = defenderId;

        Container contentPane = getContentPane();
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

        setBackground(Color.lightGray);
        addMouseListener(this);

        showLegion(attackerId, attackerChits);
        showLegion(defenderId, defenderChits);

        JButton button1 = new JButton("Offer");
        button1.setMnemonic(KeyEvent.VK_O);
        JButton button2 = new JButton("Fight");
        button2.setMnemonic(KeyEvent.VK_F);

        JPanel buttonPane = new JPanel();
        contentPane.add(buttonPane);
        buttonPane.add(button1);
        button1.addActionListener(this);
        buttonPane.add(button2);
        button2.addActionListener(this);

        pack();

        saveWindow = new SaveWindow(client, "Negotiate");

        location = saveWindow.loadLocation();
        if (location == null)
        {
            centerOnScreen();
            location = getLocation();
        }
        else
        {
            setLocation(location);
        }
        setVisible(true);
        repaint();
    }

    private void showLegion(String markerId, List chits)
    {
        Box pane = new Box(BoxLayout.X_AXIS);
        pane.setAlignmentX(0);
        getContentPane().add(pane);

        int scale = 4 * Scale.get();

        Marker marker = new Marker(scale, markerId, this, client);
        pane.add(marker);
        pane.add(Box.createRigidArea(new Dimension(scale / 4, 0)));

        List imageNames = client.getLegionImageNames(markerId);
        Iterator it = imageNames.iterator();
        while (it.hasNext())
        {
            String imageName = (String)it.next();
            Chit chit = new Chit(scale, imageName, this);
            chit.addMouseListener(this);
            chits.add(chit);
            pane.add(chit);
        }
    }

    void cleanup()
    {
        location = getLocation();
        saveWindow.saveLocation(location);
        dispose();
        client.negotiateCallback(proposal, true);
    }

    public void mousePressed(MouseEvent e)
    {
        Object source = e.getSource();
        if (attackerChits.contains(source) || defenderChits.contains(source))
        {
            Chit chit = (Chit)source;
            chit.toggleDead();
            chit.repaint();
        }
    }

    public void actionPerformed(ActionEvent e)
    {
        if (e.getActionCommand().equals("Offer"))
        {
            // Count remaining chits.
            boolean attackersLeft = false;
            Iterator it = attackerChits.iterator();
            while (it.hasNext())
            {
                Chit chit = (Chit)it.next();
                if (!chit.isDead())
                {
                    attackersLeft = true;
                    break;
                }
            }

            boolean defendersLeft = false;
            it = defenderChits.iterator();
            while (it.hasNext())
            {
                Chit chit = (Chit)it.next();
                if (!chit.isDead())
                {
                    defendersLeft = true;
                    break;
                }
            }

            // Ensure that at least one legion is completely eliminated.
            if (attackersLeft && defendersLeft)
            {
                client.showMessageDialog(
                        "At least one legion must be eliminated.");
                return;
            }

            if (!attackersLeft && !defendersLeft)
            {
                // Mutual destruction.
                proposal = new Proposal(attackerId, defenderId,
                        false, true, null, null);
            }
            else
            {
                String winnerMarkerId;
                java.util.List winnerChits;

                if (!defendersLeft)
                {
                    winnerMarkerId = attackerId;
                    winnerChits = attackerChits;
                }
                else
                {
                    winnerMarkerId = defenderId;
                    winnerChits = defenderChits;
                }

                // Ensure that the winning legion doesn't contain a dead
                // Titan.
                it = winnerChits.iterator();
                while (it.hasNext())
                {
                    Chit chit = (Chit)it.next();
                    if (chit.isDead() && chit.getId().startsWith(
                            Constants.titan))
                    {
                        client.showMessageDialog(
                            "Titan cannot die unless his whole stack dies.");
                        return;
                    }
                }

                // Remove all dead creatures from the winning legion.
                java.util.List winnerLosses = new ArrayList();
                it = winnerChits.iterator();
                while (it.hasNext())
                {
                    Chit chit = (Chit)it.next();
                    if (chit.isDead())
                    {
                        String name = chit.getId();
                        if (name.startsWith(Constants.titan))
                        {
                            name = Constants.titan;
                        }
                        winnerLosses.add(name);
                    }
                }
                proposal = new Proposal(attackerId, defenderId,
                        false, false, winnerMarkerId, winnerLosses);
            }

            // Exit this dialog.
            cleanup();
        }

        else if (e.getActionCommand().equals("Fight"))
        {
            proposal = new Proposal(attackerId, defenderId, true,
                    false, null, null);

            // Exit this dialog.
            cleanup();
        }
    }
}
