package smart_gs.util;

import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import smart_gs.GSConstants;
import smart_gs.image_search.logical.TextType;
import smart_gs.logical.LineSegment;
import smart_gs.logical.LineSegmentForEdit;
import smart_gs.logical.Preference;
import smart_gs.logical.Spread;
import sml_editor.logical.LineDirection;

public class SegfoToLineConverter {
	
		private Spread spread;
		String file_name;
		
		public SegfoToLineConverter(Spread spread){
			this.spread = spread;
			this.file_name = spread.getFileName();
		}
		
		public Pair<LineDirection,List<LineSegment>> getLines(File file){
			return getLines(file,this.file_name);
		}
		
		public Pair<LineDirection,List<LineSegment>> getLines(File file, String file_name){
			String firstLineString;
			String secondLineString;
			LineDirection lineDirection = LineDirection.UNDEFINED;
			List<LineSegment> lines = new ArrayList<LineSegment>();
			
			StringBuffer bodyBufStr = new StringBuffer();
			try{
	            FileReader fr = new FileReader(file);
	            BufferedReader br = new BufferedReader(fr);
	            String tmp_str;
	            
	            if ((firstLineString = br.readLine()) == null) {
	                System.out.println("Someting wrong to read the first line of the file: " + file);
	            	return null;
	            }
	            
	            if ((secondLineString = br.readLine()) == null) {
	            	System.out.println("Someting wrong to read the second line of the file: " + file);
	            	return null;
	            } else {
	            	secondLineString = secondLineString.trim();
	            }
	           
	            
	            if ( ! secondLineString.equalsIgnoreCase("Horizontal") && ! secondLineString.equalsIgnoreCase("Vertical")) {
	            	System.out.printf("The second line %s of the file is %s.%n It must be Vertical or Horizontal.%d", secondLineString, file);
	            } else {
	            	lineDirection = secondLineString.equalsIgnoreCase("Horizontal")?LineDirection.HORIZONTAL:LineDirection.VERTICAL;
	            }
	            
	            while((tmp_str = br.readLine()) != null){
	                bodyBufStr.append(tmp_str);
	                bodyBufStr.append('\t');
	            }
	            br.close();
	        }
	        catch(IOException e){
	            e.printStackTrace();
	            System.out.println("Something wrong to read the file: " + file);
	            return null;
	        }
	        
	        int start = firstLineString.indexOf(file_name);
	        for (int i=0;i<start;i++) {
	        	if (!Character.isWhitespace(firstLineString.indexOf(i))) {
	        		System.out.println(String.format("1st line \"%s\" does not match the spread file name: \"%s\"",firstLineString,file_name));
	        		return null;
	        	}
	        }
	        for (int i=start+file_name.length();i<firstLineString.length();i++) {
	        	if (!Character.isWhitespace(firstLineString.indexOf(i))) {
	        		System.out.println(String.format("1st line \"%s\" does not match the spread file name: \"%s\"",firstLineString,file_name));
	        		return null;
	        	}
	        }
	        
            if ( ! secondLineString.equalsIgnoreCase("Horizontal") && ! secondLineString.equalsIgnoreCase("Vertical")) {
            	System.out.printf("The second line %s of the file is %s.%n It must be Vertical or Horizontal.%d", secondLineString, file);
            } else {
            	lineDirection = secondLineString.equalsIgnoreCase("Horizontal")?LineDirection.HORIZONTAL:LineDirection.VERTICAL;
            }
			
	        String file_contents = bodyBufStr.toString();
	        String[] tokenArray = file_contents.split("[\\x20\\u0009\\u000D]+");
	        List<Integer> intList = new ArrayList<Integer>();
	        for (int i = 0;i<tokenArray.length;i++){
	        	if (tokenArray[i].isEmpty()) i++;
	        	try {
	        		int tmpInt = Integer.parseInt(tokenArray[i]);
	        		intList.add(tmpInt);
	        	} catch (NumberFormatException e) {
	        		System.out.println( String.format("%d-th element %d of  \"%s\" cannot be parsed as an integer",i,file_name,tokenArray[i]));
	        		return null;
	        	}
	        }
	        
	        if (intList.get(intList.size()-1)!=-99999) {
	        	System.out.println(String.format("The last token should be -99999, but is %d in  \"%s\" ",intList.get(intList.size()),file_name));
	        }
	        intList.remove(intList.size()-1);
	        List<Point2D> tmpPointsList = new ArrayList<Point2D>();
	        int size = intList.size();
	        int index = 0;
	        for (int i=0;i<size;i++) {
	        	int tmpIntX = intList.get(i);
	        	if (tmpIntX==-1){
	        		if (tmpPointsList.isEmpty()) {
	        			System.out.println(String.format("The line ends with %d-th element -1 is empty",i));
	        			return null;
	        		}
	        		lines.add(new LineSegment(spread,tmpPointsList,index));
	        		index++;
	        		tmpPointsList = new ArrayList<Point2D>();
	        		continue;
	        	}
	        	if (tmpIntX<0) {
	        		System.out.println(String.format("%d-th integer %d (x-axis) in the body is negative ",i,tmpIntX));
	        	}
	        	i++;
	        	if (i>=size) {
	        		System.out.println(String.format("The data did not end with -1"));
	        		return null;
	        	}
	        	int tmpIntY = intList.get(i);
	        	if (tmpIntY<0) {
	        		System.out.println(String.format("%d-th integer (y-axis) %d in the body is negative ",i,tmpIntX));
	        	}
	        	tmpPointsList.add((Point2D.Double)(new Point2D.Double((double)tmpIntX,(double)tmpIntY)));
	        }
	 
			return new Pair<LineDirection,List<LineSegment>>(lineDirection,lines);
		}
		
		public List<LineSegmentForEdit> getLinesForEdit(File file){
			return getLinesForEdit(file,this.file_name);
		}

		
		public List<LineSegmentForEdit> getLinesForEdit(File file, String file_name){
			String firstLineString;
			String secondLineString;
			LineDirection lineDirection = LineDirection.UNDEFINED;
			List<LineSegmentForEdit> lines = new ArrayList<LineSegmentForEdit>();
			
			StringBuffer bodyBufStr = new StringBuffer();
			try{
	            FileReader fr = new FileReader(file);
	            BufferedReader br = new BufferedReader(fr);
	            String tmp_str;
	            
	            if ((firstLineString = br.readLine()) == null) {
	                System.out.println("Someting wrong to read the first line of the file: " + file);
	            	return null;
	            }
	            
	            if ((secondLineString = br.readLine()) == null) {
	            	System.out.println("Someting wrong to read the second line of the file: " + file);
	            	return null;
	            }
	            
	            while((tmp_str = br.readLine()) != null){
	                bodyBufStr.append(tmp_str);
	                bodyBufStr.append('\t');
	            }
	            br.close();
	        }
	        catch(IOException e){
	            e.printStackTrace();
	            System.out.println("Something wrong to read the file: " + file);
	            return null;
	        }
	        
	        int start = firstLineString.indexOf(file_name);
	        for (int i=0;i<start;i++) {
	        	if (!Character.isWhitespace(firstLineString.indexOf(i))) {
	        		System.out.println(String.format("1st line \"%s\" does not match the spread file name: \"%s\"",firstLineString,file_name));
	        		return null;
	        	}
	        }
	        for (int i=start+file_name.length();i<firstLineString.length();i++) {
	        	if (!Character.isWhitespace(firstLineString.indexOf(i))) {
	        		System.out.println(String.format("1st line \"%s\" does not match the spread file name: \"%s\"",firstLineString,file_name));
	        		return null;
	        	}
	        }
	        
            if ( ! secondLineString.equalsIgnoreCase("Horizontal") && ! secondLineString.equalsIgnoreCase("Vertical")) {
            	System.out.printf("The second line %s of the file is %s.%n It must be Vertical or Horizontal.%d", secondLineString, file);
            } else {
            	lineDirection = secondLineString.equalsIgnoreCase("Horizontal")?LineDirection.HORIZONTAL:LineDirection.VERTICAL;
            }
			
	        String file_contents = bodyBufStr.toString();
	        String[] tokenArray = file_contents.split("[\\x20\\u0009\\u000D]+");
	        List<Integer> intList = new ArrayList<Integer>();
	        for (int i = 0;i<tokenArray.length;i++){
	        	if (tokenArray[i].isEmpty()) i++;
	        	try {
	        		int tmpInt = Integer.parseInt(tokenArray[i]);
	        		intList.add(tmpInt);
	        	} catch (NumberFormatException e) {
	        		System.out.println(String.format("%d-th element %d cannot be parsed as an integer",i,tokenArray[i]));
	        		return null;
	        	}
	        }
	        
	        if (intList.get(intList.size()-1)!=-99999) {
	        	System.out.println(String.format("The last token should be -99999, but is %d",intList.get(intList.size())));
	        }
	        intList.remove(intList.size()-1);
	        List<Point2D> tmpPointsList = new ArrayList<Point2D>();
	        int size = intList.size();
	        for (int i=0;i<size;i++) {
	        	int tmpIntX = intList.get(i);
	        	if (tmpIntX==-1){
	        		if (tmpPointsList.isEmpty()) {
	        			System.out.println(String.format("The line ends with %d-th element -1 is empty",i));
	        			return null;
	        		}
	        		lines.add(new LineSegmentForEdit(tmpPointsList,lineDirection));
	        		tmpPointsList = new ArrayList<Point2D>();
	        		continue;
	        	}
	        	if (tmpIntX<0) {
	        		System.out.println(String.format("%d-th integer %d (x-axis) in the body is negative ",i,tmpIntX));
	        	}
	        	i++;
	        	if (i>=size) {
	        		System.out.println(String.format("The data did not end with -1"));
	        		return null;
	        	}
	        	int tmpIntY = intList.get(i);
	        	if (tmpIntY<0) {
	        		System.out.println(String.format("%d-th integer (y-axis) %d in the body is negative ",i,tmpIntX));
	        	}
	        	tmpPointsList.add((Point2D.Double)(new Point2D.Double((double)tmpIntX,(double)tmpIntY)));
	        }
	 
			return lines;
		}
	}
