/*
   Casper Eyckelhof Oktober 2000
   Let op alle "hacks" om de index van 1..aantal te laten lopen!
*/
import java.util.*;
public class Tour{

    private int[] route; //indexen van de bezochte steden
    private double lengte;
    private int index; //index in de huidige tour; 1..max
    private int max; //totaal aantal bekende plaatsen in de kaart
    private boolean[] blacklist; //misschien iets misleidende naam: een stad in de blacklist is al bezocht
    private boolean[][] verbindingsGraaf;
    private Kaart kaart; //Bah, toch weer een lelijk ontwerp...
    
    Tour(int max, Kaart kaart){
        this.kaart = kaart;
        this.max = max;
        route = new int[max+1];
        lengte = 0;
        index = 1; 
        blacklist = new boolean[max+1];
        for (int i = 1; i<=max; i++){
            blacklist[i] = false;    
        }
        //er is nog geen enkele weg in de tour in gebruik
        verbindingsGraaf = new boolean[max+1][max+1];
        for (int i = 1; i <= max; i++){
         for (int j = 1; j <= max; j++){
            verbindingsGraaf[i][j] =false;
         }
        }       
    }
    
    //levert een nieuwe kopie van een tour-instantie op.
    //(hoe werkt Object.clone() eigenlijk? :)
    public Tour kloon(){
      Tour kloontje = new Tour(max,kaart); 
      kloontje.route = route;
      kloontje.lengte = lengte;
      kloontje.index = index;
      kloontje.max = max;
      kloontje.blacklist = blacklist;
      kloontje.verbindingsGraaf = verbindingsGraaf;
      return kloontje;	
    	
    }	
    
    public void voegToe(int stad){
        //eerste stad komt op index ==1 
        route[index] = stad;
        blacklist[stad]=true;  
        
        //eerste stad: speciaal geval!
        if (index != 1 ){
           verbindingsGraaf[route[index-1]][stad] = true;
           verbindingsGraaf[stad][route[index-1]] = true;
           lengte += kaart.afstand(route[index-1],stad);
        } 
        //laatste stad, nog 1 extra doen om rond te maken
        if (index == max) {
           verbindingsGraaf[route[1]][stad] = true;
           verbindingsGraaf[stad][route[1]] = true;
           lengte += kaart.afstand(route[1],stad);  
           index--; //Let op! Nu is straks index == max
        }     
        index++;
    }
    
    public boolean bevatStad(int stad){
       return blacklist[stad];    
    }
    
    public boolean blackListed(int stad){
        return blacklist[stad];   
    }  
    
    public boolean bevatWeg(int stad1, int stad2){
        return verbindingsGraaf[stad1][stad2];
    }
    
    public int[] route(){
       return route;   
    }    
    
 
    public boolean bevatWeg2(int stad1, int stad2){
    //pas op: niet symmetrisch
       boolean resultaat = false;
       for (int s = 1; s <= index; s++){
         if ((route[s] == stad1) && (route[s+1] == stad2)){
            resultaat = true;
            break;
         }   
         if ((route[index] == stad1) && (route[1] == stad2)) {
            resultaat = true;
         }
       }  
         return resultaat;
    } 
    
    public double lengte(){
       return lengte;   
    }
    
    public int aantal(){
       return index;   
    } 
    
    //index van de huidige stad
    public int current(){
        return route[index-1];    
    }
    
    
    //berekent de lengte opnieuw, nuttig als de afstand tussen steden is veranderd
    public double berekenLengte(){
    	double totnutoe = 0;
    	for (int i=1; i<max; i++){
    		totnutoe += kaart.afstand(route[i],route[i+1]); 
    	}
    	//rondje afmaken	
    	totnutoe += kaart.afstand(route[max],route[1]);
    	lengte = totnutoe;
    	return totnutoe; 
    } 	
    
    //geeft de stad na stad nummer i in de tour
    // stel tour is 2,8,1,4,5,7,6,9,3 dan is next(2)=8, next(7)=6, next(3)=2
    public int next(int i){
        boolean found = false;
        int index = 1;
        while (!found) {
           if (route[index] == i){
           	  found = true;
           } else {
              index++;	
           }			
        }		
    	if (index == max) {
    	    return route[1];
        } else {
    	    return route[index+1];
    	}	
    } 	  
                     

}