import java.util.*;
import java.text.*;
 
/********************************************************************* 
 * Congress is where the Reps interact and enact legislation for the
 * whole Population at large.  For each bill proposed, it is compared
 * to the status quo position, and all Reps vote.  Through this voting
 * Reps accumulate a voting record and use this record to adapt the
 * partyTags of other Reps.
 ********************************************************************/ 
public class Congress extends Vector { 
    public int[] statusQuo;       // The current legislation 
    public int[] newPolicy;       // The new legislation 
    public int[] proposedBills;   // A collection of the bills proposed 
    public int[] proposedIssues;  // A collection of the issues proposed 
    public int[][] proposedTags;  // A collection of the tags proposed 
    public int numOfBills;        // The number of times bills are proposed 
    public String[] didItPass;    // A record of if a bill passed or not 
    boolean OUT = false; 
 
    // The constructor initializes all our variables 
    public Congress(int policies, int positions, int numOfBills, int tagLength) { 
	statusQuo = Utilities.vectorRand(policies, positions); 
	newPolicy = new int[policies]; 
	System.arraycopy(statusQuo, 0, newPolicy, 0, statusQuo.length); 
	proposedBills = Utilities.vectorRand(numOfBills, policies); 
	proposedIssues = Utilities.vectorRand(numOfBills, positions); 
	proposedTags = new int[numOfBills][]; 
	for (int i=0; i<numOfBills; i++) 
	    proposedTags[i] = Utilities.vectorRand(tagLength, 2); 
	this.numOfBills = numOfBills; 
	didItPass = new String[numOfBills]; 
    } 
     
    // Representatives propopse bills while in congress and accumulate
    // a voting record.  The record is then used in updating their
    // party allegiances
    public void ConductBusiness() { 

	// Replace the statusQuo with the policy enacted last time. 
	System.arraycopy(newPolicy, 0, statusQuo, 0, newPolicy.length); 
 
	// Members propose legislation and the Congress votes  
	for (int i=0; i<numOfBills; i++)  
	    ProposeLegislation(i); 
 
	// Each member of Congress selects another member at random to 
	// adapt their tag. 
	for (int i=0; i<size(); i++) { 
	    Rep tempRep = (Rep)elementAt(i); 
	    int otherMember = i; 
	    while (otherMember == i) 
		otherMember = Math.abs(Utilities.rand.nextInt() % size()); 
	    // System.out.println("Rep " + i + " adapting Rep " + otherMember); 
	    tempRep.tagAdapt((Rep)elementAt(otherMember)); 
	} 
	 
	// Members update their tags 
	for (int i=0; i<size(); i++) { 
	    ((Rep)elementAt(i)).resetTag(); 
	} 
	 
	if (OUT)
	    similarityMatrix();
    }

    // Here we implement bill-proposal and voting in Congress
    public void ProposeLegislation(int voteNumber) { 
	boolean different = false; 
	Rep Author = null; 
	int issue = 0; 

	// Make sure the Author's position is different than the status quo
	while (!different) { 
	    // Find a random author 
	    Author = (Rep)elementAt(Math.abs(Utilities.rand.nextInt()  
					     % size())); 
 
	    // Have the Author propose a random issue as a bill 
	    issue = Math.abs(Utilities.rand.nextInt()  
			     % Author.ideology.length); 
 
	    // If it's different than the statusQuo, move on to legislation 
	    if (Author.ideology[issue] != newPolicy[issue]) 
		different = true; 
	} 
 
	// Store the bill and tag for future use by candidates and voters 
	proposedIssues[voteNumber] = issue; 
	proposedBills[voteNumber] = Author.ideology[issue]; 
	proposedTags[voteNumber] = Author.partyTag; 
 
	// Find out how many members vote for the proposed bill 
	int MotionToAdopt = 0; 
	for (int i=0; i<size(); i++) { 
	    Rep tempRep = (Rep)elementAt(i); 
	    MotionToAdopt += tempRep.BillVote(Author.ideology[issue], issue,  
					      newPolicy[issue],  
					      Author.partyTag, voteNumber); 
	} 
 
	// If more than half support the bill, it becomes the law 
	if (MotionToAdopt > (size()/2)) { 
	    newPolicy[issue] = Author.ideology[issue]; 
	    didItPass[voteNumber] = "Y"; 
	} 
	else 
	    didItPass[voteNumber] = "N"; 
    } 

    // Prints out the similarity matrix between member of congress's tags
    public void similarityMatrix() {
	System.err.println(""); 
	for (int i=0; i<size(); i++) { 
	    Rep currentRep = (Rep)elementAt(i); 
	    for (int j=0; j<size(); j++) { 
		Rep otherRep = (Rep)elementAt(j); 
		double similarity = currentRep.findSimilarity(otherRep.partyTag); 
		DecimalFormat pretty = new DecimalFormat(".0#"); 
		System.err.print(pretty.format(similarity) + "\t"); 
	    } 
	    System.err.println(""); 
	} 
    }

    // Output to the screen for viewing 
    public void ScreenSpew() { 
	
	System.out.println("Tags"); 
	for (int i=0; i<size(); i++) { 
	    ((Rep)elementAt(i)).showTag(); 
	} 
	
	System.out.println("Records"); 
	for (int i=0; i<size(); i++) { 
	    ((Rep)elementAt(i)).showRecord(); 
	} 
	     
	for (int i=0; i<numOfBills; i++)  
	    System.out.print(didItPass[i]); 
	System.out.println(""); 
	     
	System.out.println("Ideologies"); 
	for (int i=0; i<size(); i++) { 
	    ((Rep)elementAt(i)).showIdeology(); 
	} 
	     
	System.out.println("Congress newPolicy"); 
	for (int i=0; i<newPolicy.length; i++) 
	    System.out.print(newPolicy[i]); 
	System.out.println(""); 
    }   
} 
 

