/*
 * Maxim Gorshkov
 * www.mgorshkov.com
 * Project Euler Problem # 11
 * 
 */

import java.io.*;
import java.util.*;

public class eleven {
	//just another main method...
	public static void main(String[] args) throws FileNotFoundException{
		//to time program...
		long start = System.currentTimeMillis();
		
		processFile();
		
		//end of timing, output result.
		long end = System.currentTimeMillis();
		System.out.println("Program took: "+(end-start)+"ms");
	}
	
	/* In this method, we take the grid from the text file
	 * and process the grid to make into a 2d array.
	 * We call helper methods to check products as necessary.
	 */
	public static void processFile() throws FileNotFoundException{
		
		//define some globals
		int greatestHor = 0;
		int greatestVer = 0;
		int greatestDiagLeft = 0;
		int greatestDiagRight = 0;
		int largest = 0;
		int products[] = new int[4];
		
		int grid[][] = new int[20][20];
		
		//take the input from the textfile
		File gridFile = new File("/home/indie-max/workspace/Problem11/src/grid.txt");
		Scanner input = new Scanner(gridFile);
		String gridSpan = "";
		
		//put the results of the grid into a string
		//we'll basically have 1 long string of all the information
		//as we know that each number is two digits...
		while(input.hasNext()){
			gridSpan = input.next();
		}
		input.close();
		
		//convert to individual character...
		char[] gridUnformatted = gridSpan.toCharArray();
		
		int crt = 0;
		while(crt<gridUnformatted.length){
			for(int i = 0; i < 20; i++){
				for(int j = 0; j < 20; j++){
					String temp = ""+gridUnformatted[crt]+gridUnformatted[crt+1];//concatenate characters
					grid[i][j] = Integer.parseInt(temp);//parse these two chars as an integer
					crt += 2; //increment, win.
				}
			}
		}

		//print the grid containing just ints...
		printGrid(grid);
		
		//check from the various directions...
		greatestHor = checkLeftRight(grid);
		products[0] = greatestHor;
		
		greatestVer = checkTopBottom(grid);
		products[1] = greatestVer;
		
		greatestDiagLeft = checkDiagonalLeft(grid);
		products[2] = greatestDiagLeft;
		
		greatestDiagRight = checkDiagonalRight(grid);
		products[3] = greatestDiagRight;
		
		//loop to find the largest product
		int k = 0;
		while(k<4){
			if(products[k] > largest){
				largest = products[k];
			}
			k++;
		}
		
		//the end.
		System.out.println("Largest Product: "+largest);
	}
	/*
	 * Helper method: print the grid for proof of concept
	 */
	public static void printGrid(int grid[][]){
		for(int i = 0; i < 20; i++){
			for(int j = 0; j < 20; j++){
				System.out.print(grid[i][j]+" ");
			}
			System.out.println("");
		}
	}
	/*
	 * Helper method: Check to see what the largest product
	 * is from the left and from the right... we can encompass everything
	 * by setting the right bounds and looping through
	 */
	public static int checkLeftRight(int grid[][]){
		int tempProd = 0;
		int prod = 0;
		
		for(int i = 0; i < 20; i++){
			for(int j = 0; j < 20; j++){
				if(j<17){
					//set the bounds, find the product
					tempProd = grid[i][j]*grid[i][j+1]*grid[i][j+2]*grid[i][j+3];
					if (tempProd > prod) prod = tempProd;
				}
			}
		}
		
		System.out.println("Greatest horizontal product: "+prod);
		return prod;
	}
	/*
	 * Helper method: Check to see what the largest product
	 * is from the top and from the bottom... we can encompass everything
	 * by setting the right bounds and looping through
	 */
	public static int checkTopBottom(int grid[][]){
		int tempProd = 0;
		int prod = 0;
		
		for(int i = 0; i < 20; i++){
			for(int j = 0; j < 20; j++){
				if(i<17){
					//the same idea as above except we iterate the product over
					//the rows rather than columns.
					tempProd = grid[i][j]*grid[i+1][j]*grid[i+2][j]*grid[i+3][j];
					if (tempProd > prod) prod = tempProd;
				}
			}
		}
		
		System.out.println("Greatest vertical product: "+prod);
		return prod;
	}
	/*
	 * Helper method: Check to see what the largest product
	 * is from the the right diagonal... we can encompass everything
	 * by setting the right bounds and looping through
	 */
	public static int checkDiagonalRight(int grid[][]){
		int tempProd = 0;
		int prod = 0;
		
		for(int i = 0; i < 20; i++){
			for(int j = 0; j < 20; j++){
				if((i<17) && (j<17)){
					//as long as you stay out of the bottom right corner, you're good.
					tempProd = grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3];
					if (tempProd > prod) prod = tempProd;
				}
			}
		}
		
		System.out.println("Greatest horizontal right product: "+prod);
		return prod;
	}
	/*
	 * Helper method: Check to see what the largest product
	 * is from the left diagonal... we can encompass everything
	 * by setting the right bounds and looping through
	 */
	public static int checkDiagonalLeft(int grid[][]){
		int tempProd = 0;
		int prod = 0;
		
		for(int i = 0; i < 20; i++){
			for(int j = 0; j < 20; j++){
				if((i<17) && (j>3)){
					//carefully think about what it means to have a left diagonal answer...
					tempProd = grid[i][j]*grid[i+1][j-1]*grid[i+2][j-2]*grid[i+3][j-3];
					if (tempProd > prod) prod = tempProd;
				}
			}
		}
		
		System.out.println("Greatest horizontal left product: "+prod);
		return prod;
	}
}
