/*
 * Main.java
 *
 * Created on November 26, 2007, 12:07 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
       

import java.io.*;
import java.util.*;
import java.lang.Number.*;







/**
 *
 * @author Saurabh
 */
public class Main {
    
    final int K_Factor= 20;
    int Clust_no = 1;
    int Border_Clust = 500;
    Queue myqueue = new LinkedList();                           // To store vertices to be processed next
	Integer X, Y;                                           // Represent X and Y coordinates
        int i = 0;
        
        int Elements[][]= new int[200][5];
        int Dist[]= new int[200];
        void File_Init()
        {
           
            try
            {
                FileReader reader = new FileReader("newfile1");
            
            Scanner in = new Scanner(reader);
	// PrintWriter out = new PrintWriter (array[5]+"_dis.txt");
            String line = in.nextLine();
            while (in.hasNext())
            {
                System.out.println("Going to read");
            line = in.nextLine();
            System.out.println(line);
            String [] Line_Token = line.split("        ");
            System.out.println(Line_Token[1]);
            X = Integer.parseInt(Line_Token[1]);
            Y = Integer.parseInt(Line_Token[8]);
            System.out.println(X);
            Elements[i][0]=X;
            Elements[i][1]=Y;
            i++;
            }
        }catch(Exception e)
        {
            System.out.println(e);
        }
        }
        
                
        int Func_Dist(int X1, int Y1, int X2, int Y2)
        {
         int distance = (int)(Math.sqrt(((X2-X1)*(X2-X1)) + ((Y2-Y1)*(Y2-Y1))));
         return distance;
        }
        
        void ProcessQueue()
        {
            int size = myqueue.size();
            int point =0, pointX=0, pointY=0, dist=0;
            
            
            for(int i=0; i< size; i++)
            {
                point = (Integer)myqueue.poll();                                                 // Var point contains the index of member elements
                pointX = Elements[point][0];
                pointY = Elements[point][1];
                
                for(int j=0;j<200; j++)
                {
                    if(Elements[j][3]!=Elements[point][3])
                    {
                        dist = Func_Dist(Elements[point][0],Elements[point][1], Elements[j][0], Elements[j][0]);
                        if(dist<K_Factor)
                            Elements[j][3]=Elements[point][3];
                        else if(dist== K_Factor)
                            Elements[j][3]=Border_Clust;
                    }
                }
            }
            
         
                
            
        }
        
        int NearestK(int X1, int Y1, int K)
        {
            int Need =0;                                                                    // Represents the need to process myqueue at the end of this for or not
            
        for(int j=0; j<200; j++)
            {
                Dist[j]= Func_Dist(X1, Y1, Elements[j][0], Elements[j][1]); 
               
                // What I am gonna do now is find elements in the first cluster, then run the algo only on its member elements.
                
                if((Dist[j]<K_Factor)&&(Elements[j][3]!=K))                                                                    // If the point is closer to X, Y, give the point the same cluster
                {
                    Need =1;
                    Elements[j][3]=K;
                    myqueue.offer(j);
                }
                else if((Dist[j]>K_Factor)&&((Elements[j][3]==0)||(Elements[j][3]==500)))
                {
                    Clust_no++;
                    Elements[j][3]=Clust_no;                                                       // else assign the point to new cluster
                
                }
                else if(Dist[j]== K_Factor)
                    Elements[j][3]=Border_Clust;
                
                /* if((Dist[j]<K_Factor)&&(Elements[j][3]!=0)&&((Elements[j][3])!=K)&&(Elements[j][3]!=500) )                                        // For all elements close to the elements in question and not yet part of any cluster.
                    Elements[j][3]=Border_Clust+500;
                else if((Dist[j]<K_Factor)&&(Elements[j][3]==0))                                    // For all elements close to the elements in question and part of some cluster.
                    Elements[j][3]= K;
                else if (Elements[j][3]==K_Factor)                                                      // For all elements on the border
                    Elements[j][3]=Border_Clust;
                else if((Dist[j]>K_Factor)&&(Elements[j][3]==0))
                {
                    Elements[j][3]=Clust_no;
                    Clust_no++;
                }*/
                    
            }  
        if(Need ==1)
            ProcessQueue();
        
            Arrays.sort(Dist);
            
            return Dist[K_Factor];
            
        }
        
       
        void Calc_K_dist()
        {
            try{
                PrintWriter out = new PrintWriter ("outfile.txt");
            
                for(int i=0; i<200; i++)
                    Elements[i][3]=0;                                                                   // Initialise cluster field of all elements to zero
                
                Elements[0][3]=Clust_no;
            
                
            for(int i=0; i<200; i++)
            {
                
            Elements[i][2]= NearestK(Elements[i][0],Elements[i][1], Elements[i][3]);                    //Find and store K nearest distance
           
            out.println(Elements[i][0]+" "+ Elements[i][1]+" "+Elements[i][2]+ " " +Elements[i][3]);
            //out.println("NextLine\n");
            }
                out.close();
                System.out.println(Clust_no);
                
                PrintWriter out2 = new PrintWriter ("distance.txt");
            
                for(int h=0; h<200; h++)
                    out2.println(Elements[h][2]);
                
                out2.close();
             
            }catch(Exception e)
            {
               System.out.println("Error in outfile"+e);
            }
            
        }
        


        
    /*
     
     
     */    
        

    
    /** Creates a new instance of Main */
   
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Main tempObj = new Main();
        tempObj.File_Init();
        tempObj.Calc_K_dist();
        
        
        
        // TODO code application logic here
    }
    
}
