import java.util.*;

/**
 * Utilities is here for helpful stuff, like a random variable, 
 * and a random vector generator.  All of the ideologies, tags, and
 * positions are created randomly here.
 */ 
public class Utilities { 
    /**
     * Gives us an random number generator to work with
     */
    public static Random rand = new Random(); 
    /**
     * Pascal's triangle up to row 41 for use in tag visualization
     */
    public static long[][] Pascal = buildPascal(41);

    /**
     * Creates a positive randomized int array
     * @param size the size of the array needed
     * @param modparam the number of possible values 
     * @return returns the randomized int array
     */
    public static int[] vectorRand(int size, int modparam) { 
        int vector[] = new int[size]; 

        for (int i=0; i<size; i++) 
            vector[i] = Math.abs(rand.nextInt() % modparam); 
        return(vector); 
    } 

    /**
     * Creates a positive randomized int array around a center int
     * @param size the size of the array needed
     * @param modparam the number of possible values 
     * @param c the center of the array
     * @return returns the randomized int array
     */
    public static int[] vectorRand(int size, int modparam, int c) { 
	int vector[] = new int[size]; 

	for (int i=0; i<size; i++) { 
	    boolean ok = false; 
	    int opinion = 0; 
	    while (!ok) { 
		ok = true; 
		opinion = c + rand.nextInt() % 3; 
		if (opinion >= modparam) ok = false; 
		if (opinion < 0) ok = false; 
	    } 
	    vector[i] = opinion; 
	} 
	return(vector); 
    } 
 
    /**
     * Creates a randomized double array
     * @param size the size of the array needed
     * @return returns the randomized double array
     */
    public static double[] vectorRand(int size) { 
	double vector[] = new double[size]; 

	for (int i=0; i<size; i++) 
	    vector[i] = rand.nextDouble(); 
	return(vector); 
    } 
 
    /**
     * Creates a vector with values within the bounds of the modparam 
     * that has consistent values around the value c. c is generated 
     * randomly on each calling
     * @param size the size of the array needed
     * @param modparam the number of possible values
     * @return returns the consistent randomized int array
     */
    public static int[] vectorConsist(int size, int modparam) { 
	int vector[] = new int[size]; 
 	int c = Math.abs(rand.nextInt() % modparam);  

	for (int i=0; i<size; i++) { 
	    int p = Math.abs(rand.nextInt() % 3); 
	    if (p == 0 && c != 0) 
		vector[i] = c-1; 
	    else if (p == 2 && c != modparam-1)  
		vector[i] = c+1; 
	    else  
		vector[i] = c; 
       	} 
	return(vector); 
    } 
 
    /**
     * Creates a vector with values within the bounds of the modparam 
     * that has consistent values around the value c. c comes from an
     * outside paramater rather than within the method 
     * @param size the size of the array needed
     * @param modparam the number of possible values
     * @param c the center of the array
     * @return returns the consistent randomized int array
     */
    public static int[] vectorConsist(int size, int modparam, int c) { 
	int vector[] = new int[size]; 
 
	for (int i=0; i<size; i++) { 
	    int p = Math.abs(rand.nextInt() % 3); 
	    if (p == 0 && c != 0) 
		vector[i] = c-1; 
	    else if (p == 2 && c != modparam-1)  
		vector[i] = c+1; 
	    else  
		vector[i] = c; 
       	} 
	return(vector); 
    } 
 
    /**
     * Computes the sigmoid function on a given input.  Useful for laziness 
     * @param x the number for sigmoid calculation
     */
    public static double Sigmoid(double x) { 

	return(1 / (1 + Math.exp(-x))); 
    } 
 
    /**
     * Computes Pascal's triangle up to the number N
     * @param N the depth of the triangle
     */
    public static long[][] buildPascal(int N) {
	long [][] triangle = new long[N][];
	
	// Create the arrays for each level of the triangle
	for (int i=0; i<triangle.length; i++) {
	    triangle[i] = new long[i+1];
	}
	
	// Fill in the values for all rows of the triangle
	for (int i=0; i<triangle.length; i++) {
	    triangle[i][0] = 1;
	    for (int j=1; j<triangle[i].length-1; j++) {
		triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
	    }
	    triangle[i][triangle[i].length - 1] = 1;
	}
	return(triangle);
    }

    /**
     * Pauses the program until the user hits a key
     * @param msg a meaningless String for the keystroke
     */
    public static void waitHere(String msg) { 
	System.out.print(msg); 
	try { System.in.read(); } 
	catch(Exception e) {} // Ignore any errors while reading. 
    } 
} 


