package pacman;
import static pacman.MsPacInterface.width;
import java.awt.*;
import java.util.ArrayList;

import games.math.Vector2d;

public class Agent implements Drawable {

    int x, y;
    int w, h;
    Color color;

    static int[] dirs = {-width, 1, width, -1};
    static Vector2d[] vDirs = {
            new Vector2d(0, -1),
            new Vector2d(1, 0),
            new Vector2d(0, 1),
            new Vector2d(-1, 0),
    };
    static int pill = MsPacInterface.pill & 0xFFFFFF;
    static int pacMan = MsPacInterface.pacMan & 0xFFFFFF;
    static int lips = MsPacInterface.blinky & 0xFFFFFF;

    int[] d;
    int move;

    Vector2d cur, prev, tmp;


    final static int pacmanMustEatGhost=0;
    final static int pacmanMustRunAwayFromGhost=1;
    final static int pacmanMustEatPowerPill=2;
    final static int pacmanMustEatPills=3;
    final static int pacmanMustGetInTunnel=4;


    public int definGoal(ArrayList rf,ArrayList wf){

        //TODO
        return 0;

    }

    public int findDirection(int goal){

       //TODO

        return 0;
    }


    public Agent() {
        d = new int[]{20, 20, 20, 20};
        prev = new Vector2d();
        cur = new Vector2d();
        tmp = new Vector2d();
        System.out.println("new agent");
    }

    public Agent(ConnectedSet cs, int[] pix) {
        this();
        update(cs, pix);
    }

    public void update(ConnectedSet cs, int[] pix) {
        cs.validate();
        w = cs.width;
        h = cs.height;
        prev.set(x, y);
        x = cs.xMin + w / 2;
        y = cs.yMin + h / 2;
        cur.set(x, y);
        // now check lines
        // System.out.println(cur + " : " + x + " : " + y);
        for (int i = 0; i < dirs.length; i++) {
            d[i] = search(x + y * width, pix, dirs[i]);
            // System.out.println(i + "\t " + d[i]);
        }
        this.color = cs.c;
    }

    public int move(GameState gs) {

        move = -1;

        double best = 100000;
        for (int i = 0; i < dirs.length; i++) {
            if (d[i] > 12) {
                tmp.set(cur);
                tmp.add(vDirs[i]);
                // System.out.println(i + "\t " + eval(tmp, gs));
                if (eval(tmp, gs) < best) {
                    move = i;
                    best = eval(tmp, gs);
                }
            }
        }
        if (move < 0) {
            System.out.println("Move error: " + move);
            // move = 3;
        }
        move += 1;
        // System.out.println(move);
        return move;
    }

 // 1=UP
 // 2=RIGHT
 // 3=DOWN
 // 4=LEFT

    int lastMove=-1;

    public int move2(GameState gs) {
            move = -1;
            double best = 1000000;
            double lastVal=2000000;
        double val=1000000;
     //   System.out.println("CUR : "+ cur.x/8 +" "+cur.y/8);
            for (int i = 0; i < dirs.length; i++) {
           //     if (d[i] > 12) {
                    tmp.set(cur.x,cur.y);

                    if(cur.y/8==8 && (cur.x/8==26||cur.x/8==27) && i==1)
                        tmp.set(8,64);
                    else if(cur.y/8==8 && (cur.x/8==1||cur.x/8==0) && i==3)
                        tmp.set(208,64);
                    else if(cur.y/8==17 && (cur.x/8==26||cur.x/8==27) && i==1)
                        tmp.set(8,136);
                    else if(cur.y/8==17 && (cur.x/8==1||cur.x/8==0) && i==3)
                       tmp.set(208,136);
                    else
                        tmp.add(vDirs[i],8);

                    if(tmp.x/8<1 || tmp.x/8 >27 || tmp.y/8<1 || tmp.y/8>30 || gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==8
                            || gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==1 || gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==2
                            || gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==3 || gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==4
                            || gs.gameBoard.board[(int)(tmp.y/8+vDirs[i].y)][(int)(tmp.x/8+vDirs[i].x)]==1
                            || gs.gameBoard.board[(int)(tmp.y/8+vDirs[i].y)][(int)(tmp.x/8+vDirs[i].x)]==2
                            || gs.gameBoard.board[(int)(tmp.y/8+vDirs[i].y)][(int)(tmp.x/8+vDirs[i].x)]==3
                            || gs.gameBoard.board[(int)(tmp.y/8+vDirs[i].y)][(int)(tmp.x/8+vDirs[i].x)]==4) {
                        continue;
                    }
                    if(gs.gameBoard.board[(int)tmp.y/8][(int)tmp.x/8]==5){
                        lastMove=i;
                        move=i+1;
                        return move;

                    }

                    val=eval2(tmp,gs);
            //    System.out.println(i+" : "+val);
                    if (val < best) {
                        move = i;
                        best = val;
                    }
                    if(i==lastMove)
                        lastVal=val;
           //     }
            }
            if(move==(lastMove+2)%4 ){
                if(lastVal<=best+250){
                    move = lastMove;
                }
            }
            lastMove=move;
        System.out.println(move);
            if (move < 0) {
                System.out.println("Move error: " + move);
                // move = 3;
            }
            move += 1;
            // System.out.println(move);
            return move;
        }


    public double eval(Vector2d pos, GameState gs) {

        // IF in edible phase
        //move towards pills
        // and towards the ghosts

        double val=0;
        double ghostDis, edibleDis, pillDis,secondGhostDis,secondEdibleDis,
                powerPillDis ;

        if(gs.edible){

   //         System.out.println("CAN EAT GHOSTS");
            if (gs.closestPill != null) {
                 pillDis=pos.dist(gs.closestPill);
            } else {
                pillDis=0;
            }

            if(gs.closestEdible !=null){
                edibleDis=pos.dist(gs.closestEdible);
            }
            else{
              edibleDis=0;
            }

            if(gs.secondEdible !=null){
                secondEdibleDis=pos.dist(gs.secondEdible);
            }
            else{
              secondEdibleDis=0;
            }

            val= val + (100*pillDis+50*edibleDis+10*secondEdibleDis);
            return val;
        }

        // IF not in edible phase
        // move towards pills
        //  and away from ghosts
        else{

   //         System.out.println("cant eat ghosts");
            val=0;
            if (gs.closestPill != null) {
                 pillDis=pos.dist(gs.closestPill);

            } else {
                pillDis=0;
            }
            if(gs.closestGhost != null){
                ghostDis=pos.dist(gs.closestGhost);
             }
             else{
                 ghostDis=0;
             }

             if(gs.secondGhost != null) {
                secondGhostDis=pos.dist(gs.secondGhost);
             }
             else{
                 secondGhostDis=0;

             }

            //val=val-(pillDis);
//            val=val+(100*ghostDis);
            val=val+200*pillDis;
            val=val-(200*ghostDis);
            return val;
        }

    }

    private int search(int p, int[] pix, int delta) {
        int len = 0;
        int pp = pix[p] & 0xFFFFFF;
        try {
            while (pp == 0 || pp == pacMan || pp == pill || pp == lips) {
                len++;
                if (len > width) return width;
                p += delta;
                pp = pix[p] & 0xFFFFFF;
            }
        } catch (Exception e) {
        }
        // System.out.println(pp);
        return len;
    }


    public void draw(Graphics gg, int ww, int hh) {
        Graphics2D g = (Graphics2D) gg;
        g.setColor(color);
        g.fillRect(x - w / 2, y - h / 2, w, h);
        // now the four lines
        g.setColor(Color.green);
        g.drawLine(x, y, x, y - d[0]);
        g.drawLine(x, y, x + d[1], y);
        g.drawLine(x, y, x, y + d[2]);
        g.drawLine(x, y, x - d[3], y);
        g.setColor(Color.red);
        if (move > 0) {
            // g.setStroke();
            tmp.set(vDirs[move - 1]);
            tmp.mul(20);
            g.drawLine(x, y, x + (int) tmp.x, y + (int) tmp.y);
        }
        // g.setColor(Color.magenta);
        // g.fillOvl
    }

    public double eval2(Vector2d pos, GameState gs) {

            double val=0;
            double ghostDis, edibleDis, pillDis,secondGhostDis,secondEdibleDis,powerPillDis, secondPillDis ;

            if(gs.edible){
                         System.out.println("CAN EAT GHOSTS");
                if (gs.closestPill != null) {
                    // pillDis=pos.dist(gs.closestPill);
                    pillDis=gs.gameBoard.distance(pos,gs.closestPill);
                } else {
                    pillDis=0;
                }

                 if (gs.secondPill != null) {
                     secondPillDis=gs.gameBoard.distance(pos,gs.secondPill);

                } else {
                    secondPillDis=0;
                }

                if(gs.closestEdible !=null){
                    edibleDis=gs.gameBoard.distance(pos,gs.closestEdible);
                }
                else{
                  edibleDis=0;
                }

                if(gs.secondEdible !=null){
                    secondEdibleDis=gs.gameBoard.distance(pos,gs.secondEdible);
                }
                else{
                  secondEdibleDis=0;
                }
                //130 100 10
                val=130*pillDis+100*secondPillDis+250*edibleDis+10*secondEdibleDis;
                return val;
            }

            else{

                val=0;
                if (gs.closestPill != null) {
                     pillDis=gs.gameBoard.distance(pos,gs.closestPill);

                } else {
                    pillDis=0;
                }

                if (gs.secondPill != null) {
                     secondPillDis=gs.gameBoard.distance(pos,gs.secondPill);

                } else {
                    secondPillDis=0;
                }

                if(gs.closestGhost != null){
                    ghostDis=gs.gameBoard.distance(pos,gs.closestGhost);
                 }
                 else{
                     ghostDis=0;
                 }

                 if(gs.secondGhost != null) {
                    secondGhostDis=gs.gameBoard.distance(pos,gs.secondGhost);
                 }
                 else{
                     secondGhostDis=0;

                 }
                 if(gs.closestPowerPill != null) {
                    powerPillDis=gs.gameBoard.distance(pos,gs.closestPowerPill);
                 }
                 else{
                     powerPillDis=0;

                 }

                val=val+210*pillDis+190*secondPillDis;//+(100-ghostDis)*powerPillDis;
                val=val-(200*ghostDis); //+30*secondGhostDis*secondGhostDis);
                return val;
            }

        }


}

