/*
 * TSPInstance.java
 *
 * Created on April 6, 2006, 4:37 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package cz.pcland.tsp;
import cz.pcland.ga.GenerationInfo;
import cz.pcland.ga.MyRand;
import cz.pcland.gavisualization.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import cz.pcland.functions.lexan.*;
import cz.pcland.functions.nodes.*;
import cz.pcland.functions.syntax.*;
import cz.pcland.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.IOException;
/**
 *
 * @author petr
 */
public class TSPInstance implements Loadable{
    //double[][] data;
    Vector possitions = new Vector();
    GenerationInfo info = null;
    public LengthMatrix lmatrix;
    
    public LengthMatrix getLengthMatrix(){
        return lmatrix;
    }
    
    public void computeMatrix(){
        lmatrix = new LengthMatrix();
        lmatrix.loadFromPositions(this.possitions);
    }
    
    public void setGaInfo(GenerationInfo info){
        this.info = info;
    }
       
    public void addCity(City city) {
        if (possitions == null) possitions = new Vector();
        possitions.add(city);
    }
    
    public void removeCity(City city) {
        possitions.remove(city);
    }
    
    public String getString() {
      StringWriter out = new StringWriter();
      try {

       
        out.write("<?xml version=\"1.0\" ");
        out.write("encoding=\"UTF-8\"?>\r\n");
        out.write("<TSM>\r\n");
       
        for(int i = 0; i < this.getCount(); i++) {
          out.write("<point>\r\n");
          out.write("<x>" + getCoordinates(i).x + "</x>\r\n");
          out.write("<y>" + getCoordinates(i).y + "</y>\r\n");
          out.write("</point>\r\n");
      
        }
        out.write("</TSM>\r\n");
      
        out.flush();  // Don't forget to flush!
        out.close();
        
      }

      
      catch (IOException e) {
        System.out.println(e.getMessage());
      }
      return out.toString();
    }
    
    public void loadFromString(String str){
         try {
            InputSource inputSource = null;
            inputSource = new InputSource(new StringReader(str));
            XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
            org.xml.sax.ContentHandler handler = new TSMHandler(this);
            org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
            parser.setContentHandler(handler);
            parser.parse(inputSource);
           
        } catch (Exception e) {
            System.err.println(e + "error");
        }
    }
    
    public void deleteAll(){
        this.possitions.clear();
        info = null;
      //  possitions = null;
    }
    
    public int getCount() {
        return possitions.size();
    }
    
    
    public void makeRandom(int cities, int maxX, int maxY) {
       for(int ii=0;ii<cities;++ii) {
           City c = new City(Math.abs(MyRand.getInt()%maxX), Math.abs(MyRand.getInt()%maxY));
           this.addCity(c);
       }
    }
    
    public Point getCoordinates(int index) {
         int x = ((City)possitions.get(index)).x;
         int y = ((City)possitions.get(index)).y;
         Point p = new Point(x,y);
         return p;
    }
    
    public static Point getCoordinates(Vector pos, int index) {
         int x = ((City)pos.get(index)).x;
         int y = ((City)pos.get(index)).y;
         Point p = new Point(x,y);
         return p;
    }
    
    public String toString(){
        return String.valueOf(getCount()) + " cities.";
    }
    
    /**
     * Creates a new instance of TSPInstance
     */
    public TSPInstance() {
        
    }
    
   
    
}

class TSMHandler extends DefaultHandler {
    TSPInstance instance = null;
    private boolean inTSM = false;
    private boolean inPoint = false;
    private boolean inX = false;
    private boolean inY = false;
    private int x = 0;
    private int y = 0;
    boolean xLoaded = false;
    boolean yLoaded = false;
    //Vector items;
    
    public TSMHandler(TSPInstance instance){
        super();
        this.instance = instance;
        instance.deleteAll();
      //  items = new Vector();
    }
    
    public void startElement(String namespaceURI, String localName, String qualifiedName, Attributes atts) throws SAXException {
        if(localName.equals("TSM")) inTSM = true;
        if(localName.equals("point")) inPoint = true;
        if(localName.equals("x")) inX = true;
        if(localName.equals("y")) inY = true;
       
    }
    
    public void endElement(String namespaceURI, String localName, String qualifiedName) throws SAXException {
        
        if(localName.equals("TSM")) inTSM = false;
        if(localName.equals("point")) inPoint = false;
        if(localName.equals("x")) inX = false;
        if(localName.equals("y")) inY = false;
      
    }
    
    public void endDocument() throws SAXException {
        //KnapSack.items = this.items;
    }
    
    public void characters(char[] ch, int start, int length) throws SAXException {
        
        if(xLoaded && yLoaded) {
            this.instance.addCity(new City(x,y));
            xLoaded = false;
            yLoaded = false;
        }
        
        if(inPoint) {
            
            if(inX){
                String tmp = "";
                for (int i = start; i < start+length; i++) {
                    tmp += ch[i];
                }
                x = Integer.parseInt(tmp);
                xLoaded = true;
            }
            
            if(inY){
                String tmp = "";
                for (int i = start; i < start+length; i++) {
                    tmp += ch[i];
                }
                y = Integer.parseInt(tmp);
                yLoaded = true;
            }
            
        }
        
        
    }
    
    
}
