/* CVS: $Id: GameBoard.java,v 1.23 2001/03/17 11:47:07 gvijf Exp $ */

package gui;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import evolution.WorldController;
import evolution.InfoList;
import evolution.SystemMessage;
import evolution.events.*;

public class GameBoard extends JTable implements evolution.events.Observer {

    public GameBoard(WorldController worldController) {
        setModel(new IconTable(worldController.getWidth(), worldController.getHeight()));
        this.worldController = worldController;
        this.resourcePath = worldController.getResourcePath();
        cache = new ImageCache();
        EventManager.getInst().subscribe(this, SquareChangedEvt.class);
        init();
    }

    protected void init() {
        setAutoResizeMode(AUTO_RESIZE_OFF);
        setRowHeight(31);
        sizeColumnsToFit(AUTO_RESIZE_OFF);
        setTableHeader(null);
        setRowSelectionAllowed(false);
        int cols = getColumnCount();
        TableColumnModel tcm = getColumnModel();
        for (int i = 0; i < cols; i++) {
            tcm.getColumn(i).setPreferredWidth(31);
            tcm.getColumn(i).setMaxWidth(31);
            tcm.getColumn(i).setMinWidth(31);
        }
        for (int i = 0; i < getRowCount(); i++) {
            for (int j = 0; j < getColumnCount(); j++) {
                paintUnexploredSquare(i, j);
            }
        }
        worldController.refresh();
    }

    protected void paintUnexploredSquare(int row, int column) {
        BufferedImage bimg = new BufferedImage(30, 30, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics g = bimg.createGraphics();
        ImageIcon img = cache.get(resourcePath + landStatePath + "Unexplored.gif");
        if (img != null)
            g.drawImage(img.getImage(), 0, 0, 30, 30, 0, 0,
                img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: Unexplored.gif");
        setValueAt(new ImageIcon(bimg), row, column);
    }

    protected void paintSquare(int row, int column, SquareChangedEvt sq) {
        BufferedImage bimg = new BufferedImage(30, 30, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics g = bimg.createGraphics();
        if (sq.getLandState() != null) {
            paintLandState(g, 0, 0, 30, 30, sq.getLandState());
            if (sq.getConstructionState() != null)
                paintConstrState(g, 0, 0, 30, 30, sq.getConstructionState());
        }
        if (sq.getHumanState() != null)
            paintHumanState(g, 0, 0, 30, 30, sq.getHumanState());
        if (sq.getHumanEnergyBufferState() != null)
            paintHumanEnergyBufferState(g, 0, 0, 30, 30, sq.getHumanEnergyBufferState());
        if (sq.isActive())
            paintActiveState(g, 0, 0, 30, 30);
        else if (sq.isSelected())
            paintSelectedState(g, 0, 0, 30, 30);
        setValueAt(new ImageIcon(bimg), row, column);
    }

    /** Paint the land state on the graphics context. */
    protected void paintLandState(Graphics g, int x, int y, int w, int h, String landState) {
        ImageIcon img = cache.get(resourcePath + landStatePath + landState + ".gif");
        if (img != null)
	        g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0,
			       img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: " + landState + ".gif");
    }

    /** Paint the construction state on the graphics context. */
    protected void paintConstrState(Graphics g, int x, int y, int w, int h, String constrState) {
        ImageIcon img = cache.get(resourcePath + constructionPath + constrState + ".gif");
        if (img != null)
    	    g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0, img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: " + constrState + ".gif");
    }

    /** Paint the human state on the graphics context. */
    protected void paintHumanState(Graphics g, int x, int y, int w, int h, String humanState) {
        ImageIcon img = cache.get(resourcePath + humanPath + humanState + ".gif");
		if (img != null)
	        g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0, img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: " + humanState + ".gif");
    }

    /** Paint the human energy buffer state on the graphics context. */
    protected void paintHumanEnergyBufferState(Graphics g, int x, int y, int w, int h, String energyState) {
        ImageIcon img = cache.get(resourcePath + humanPath + energyState + ".gif");
	    if (img != null)
	        g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0, img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: " + energyState + ".gif");
    }


    /** Paint an active state on the graphics context. */
    protected void paintActiveState(Graphics g, int x, int y, int w, int h) {
        ImageIcon img = cache.get(resourcePath + selectionPath + "selected-active.gif");
        if (img != null)
	        g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0, img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: selected-active.gif");
   }

    /** Paint a selected state on the graphics context. */
    protected void paintSelectedState(Graphics g, int x, int y, int w, int h) {
        ImageIcon img = cache.get(resourcePath + selectionPath + "selected.gif");
        if (img != null)
	        g.drawImage(img.getImage(), x, y, x + w, y + h, 0, 0, img.getIconWidth(), img.getIconHeight(), null);
        else SystemMessage.message("Can't find image: selected.gif");
    }

    public boolean editCellAt(int row, int column, EventObject e) {
        selectSquare(row, column);
        return false;
    }

    protected void selectSquare(int row, int column) {
        try {
            worldController.selectSquareOfLand(row, column);
        } catch (evolution.lands.IllegalPlacementException e) {
            SystemMessage.message(e.getMessage());
        }
        EventManager.getInst().signalEvent(new SquareSelectedEvt());
    }

    public void update(evolution.events.Event event) {
        if (event instanceof SquareChangedEvt) {
            SquareChangedEvt sq = (SquareChangedEvt)event;
            paintSquare(sq.getX(), sq.getY(), sq);
            repaint();
        }
    }

    private WorldController worldController;
    private String resourcePath;
	/* The path containing the images for the different land states. */
    private String landStatePath = "images/lands/";
	/* The path containing the images for the different construction states. */
    private String constructionPath = "images/constructions/";
	/* The path containing the images for the different human states. */
    private String humanPath = "images/humans/";
    /* The path containing the images for the different selection states. */
    private String selectionPath = "images/selections/";
    private ImageCache cache;
}
