/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.xemelios.ui.ia;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Joueur {

    private static int vrx[][] = new int[3][3];
    private static int vry[][] = new int[3][3];

    static {
        for (int i = 0; i < 9; i++) {
            vrx[i % 3][i / 3] = 4 * ((i % 3) - 1);
            vry[i % 3][i / 3] = 4 * ((i / 3) - 1);
        }
    }

    private int rep[][] = new int[10][10];
    private int val[][] = new int[10][10];

    private String marque;
    private Icon icon;

    public Joueur(String s, Icon icon) {
        super();
        this.marque = s;
        this.icon = icon;
    }

    public void joue(JPanel jPanelJeu) {
        modelise(jPanelJeu);
        decide(jPanelJeu);
    }

    public int sgn(int i) {
        return i == 0 ? 0 : i < 0 ? -1 : 1;
    }

    public int compte_pion(int dx, int dy, int fx, int fy, int v) {
        boolean cnt = true;
        int cpt = 0;
        while (((dx != fx) || (dy != fy)) && cnt) {
            dx += sgn(fx - dx);
            dy += sgn(fy - dy);
            if ((dx >= 0) && (dx <= 9) && (dy >= 0) && (dy <= 9) && (rep[dx][dy] == v)) {
                cpt++;
            } else cnt = false;
        }
        return cpt;
    }

    public int compte_case(int dx, int dy, int fx, int fy) {
//        boolean cnt = true;
        int cpt = 0;
        if ((dx >= 0) && (dx <= 9) && (dy >= 0) && (dy <= 9))
            cpt++;
        while ((dx != fx) || (dy != fy)) {
            dx += sgn(fx - dx);
            dy += sgn(fy - dy);
            if ((dx >= 0) && (dx <= 9) && (dy >= 0) && (dy <= 9))
                cpt++;
        }
        return cpt;
    }

    public int evalue(int dx, int dy, int fx, int fy, int v) {
        boolean cnt = true;
        int cpt = 0, ind = 0;
        while (((dx != fx) || (dy != fy)) && cnt) {
            dx += sgn(fx - dx);
            dy += sgn(fy - dy);
            ind++;
            if ((dx >= 0) && (dx <= 9) && (dy >= 0) && (dy <= 9) && (rep[dx][dy] == v)) {
                cpt += rep[dx][dy] * (5 - ind);
            } else if ((dx >= 0) && (dx <= 9) && (dy >= 0) && (dy <= 9)) {
                cnt = (rep[dx][dy] == 0);
                cpt += rep[dx][dy] * (5 - ind);
            } else cnt = false;
        }
        return cpt;
    }

    public void valorise(int x, int y) {
        int cpt;

        for (int i = 0; i < 4; i++) {
            cpt = 1;
            cpt += compte_pion(x, y, vrx[i % 3][i / 3] + x, vry[i % 3][i / 3] + y, rep[x][y]);
            cpt += compte_pion(x, y, vrx[(8 - i) % 3][(8 - i) / 3] + x, vry[(8 - i) % 3][(8 - i) / 3] + y, rep[x][y]);
            if (cpt > Math.abs(val[x][y])) {
                val[x][y] = cpt;
            }
        }
    }

    public void modelise(JPanel jp) {
//        java.awt.Color c = new java.awt.Color(212, 208, 200);
        for (int i = 0; i < jp.getComponentCount(); i++) {
            ((JButton)jp.getComponent(i)).setBackground(Plateau.BACK_COLOR);
            rep[i % 10][i / 10] = ((JButton)jp.getComponent(i)).getActionCommand() == "" ? 0 : ((JButton)jp.getComponent(i)).getActionCommand() == marque ? 1 : -1;
        }

        for (int i = 0; i < 10; i++)
            java.util.Arrays.fill(val[i], 0);
    }

    public void projete(int x, int y) {
        int pls, mns;
        for (int i = 0; i < 4; i++) {
            pls = 0;
            mns = 0;
            if (compte_case(vrx[i % 3][i / 3] + x, vry[i % 3][i / 3] + y, vrx[(8 - i) % 3][(8 - i) / 3] + x, vry[(8 - i) % 3][(8 - i) / 3] + y) >= 5) {
                mns += evalue(x, y, vrx[i % 3][i / 3] + x, vry[i % 3][i / 3] + y, -1);
                mns += evalue(x, y, vrx[(8 - i) % 3][(8 - i) / 3] + x, vry[(8 - i) % 3][(8 - i) / 3] + y, -1);
                pls += evalue(x, y, vrx[i % 3][i / 3] + x, vry[i % 3][i / 3] + y, 1);
                pls += evalue(x, y, vrx[(8 - i) % 3][(8 - i) / 3] + x, vry[(8 - i) % 3][(8 - i) / 3] + y, 1);
            }
            if (Math.abs(mns) > Math.abs(val[x][y]))
                val[x][y] = mns;
            if (Math.abs(pls) > Math.abs(val[x][y]))
                val[x][y] = pls;
        }
    }

    public void decide(JPanel jPanelJeu) {
        int scr = 0, scp = 50;

        for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                if (rep[j][i] == 0)
                    projete(j, i);

        for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                if (rep[j][i] == 0) {
                    if (Math.abs(val[j][i]) > scr) {
                        scr = Math.abs(val[j][i]);
                        scp = j + i * 10;
                    } else {
                        if (Math.abs(rep[j][i]) == scr) {
                            if (val[j][i] >= val[scp % 10][scp / 10]) {
                                scp = j + i * 10;
                            }
                        }
                    }
                }

        rep[scp % 10][scp / 10] = 1;
        ((JButton)jPanelJeu.getComponent(scp)).setActionCommand(marque);
        ((JButton)jPanelJeu.getComponent(scp)).setIcon(icon);
        ((JButton)jPanelJeu.getComponent(scp)).setForeground(java.awt.Color.red);
        ((JButton)jPanelJeu.getComponent(scp)).setBackground(java.awt.Color.white);
    }

    public boolean victoire(JPanel jp) {
        boolean cnt = false;

        for (int i = 0; i < jp.getComponentCount(); i++) {
            rep[i % 10][i / 10] = ((JButton)jp.getComponent(i)).getActionCommand() == "" ? 0 : ((JButton)jp.getComponent(i)).getActionCommand() == marque ? 1 : -1;
        }

        for (int i = 0; i < 10; i++)
            java.util.Arrays.fill(val[i], 0);

        for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                if (rep[j][i] != 0)
                    valorise(j, i);

        for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                if (Math.abs(val[j][i]) == 5) {
                    ((JButton)jp.getComponent(j + i * 10)).setBackground(java.awt.Color.white);
                    cnt = true;
                }

        return cnt;
    }

//    public void dump(JTextArea jTextArea) {
//        for (int i = 0; i < 10; i++) {
//            for (int j = 0; j < 10; j++)
//                jTextArea.append("\t" + rep[j][i] + "(" + val[j][i] + ")");
//            jTextArea.append("\n");
//        }
//        jTextArea.append("\n");
//    }

	public String getMarque() {
	    return marque;
    }
	public Icon getIcon() {
	    return icon;
	}
}
