package jp.ac.nii.icpc2010.players;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import jp.ac.nii.icpc2010.playfield.IPlayField;

// Player that moves to the point from which the longest hilbert curve can be drawn.
public class OneCornerRouteSelecter extends BaseRouteSelecter {

    private Point routes[][];

    public OneCornerRouteSelecter(int id, IPlayField playField) {
        super(id, playField);

        List<Point[]> routes = new ArrayList<Point[]>();

        int width = playField.getWidth();
        int height = playField.getHeight();

        // right, left
        for(int i = 0; i < width - 1; i++){
            int len = i + height;
            Point[] rightUp   = new Point[len];
            Point[] rightDown = new Point[len];
            Point[] leftUp    = new Point[len];
            Point[] leftDown  = new Point[len];

            for(int j = 0; j < i; j++){
                rightUp[j] = rightDown[j] = new Point(  j + 1 , 0);
                leftUp[j]  = leftDown[j]  = new Point(-(j + 1), 0);
            }
            for(int j = 0; j < height; j++){
                rightUp[i + j]   = new Point( i,   j + 1);
                rightDown[i + j] = new Point( i, -(j + 1));
                leftUp[i + j]    = new Point(-i,   j + 1);
                leftDown[i + j]  = new Point(-i, -(j + 1));
            }

            routes.add(rightUp);
            routes.add(rightDown);
            routes.add(leftUp);
            routes.add(leftDown);
        }

        // up, down
        for(int i = 0; i < height - 1; i++){
            int len = i + width;
            Point[] upRight   = new Point[len];
            Point[] upLeft    = new Point[len];
            Point[] downRight = new Point[len];
            Point[] downLeft  = new Point[len];

            for(int j = 0; j < i; j++){
                upRight[j]   = upLeft[j]   = new Point(0,   j + 1);
                downRight[j] = downLeft[j] = new Point(0, -(j + 1));
            }
            for(int j = 0; j < width; j++){
                upRight[i + j]   = new Point(  j + 1 ,  i);
                upLeft[i + j]    = new Point(-(j + 1),  i);
                downRight[i + j] = new Point(  j + 1 , -i);
                downLeft[i + j]  = new Point(-(j + 1), -i);
            }

            routes.add(upRight);
            routes.add(upLeft);
            routes.add(downRight);
            routes.add(downLeft);
        }

        this.routes = new Point[routes.size()][];
        for(int i = 0; i < this.routes.length; i++){
            this.routes[i] = routes.get(i);
        }
    }

    @Override
    protected int getNumOfRoutes() {
        return super.getNumOfRoutes() + this.routes.length;
    }

    @Override
    protected Point[] getRoute(int routeId) {
        if(routeId < super.getNumOfRoutes()){
            return super.getRoute(routeId);
        }else{
            return this.routes[routeId - super.getNumOfRoutes()];
        }
    }
}
