/*
 * KnapSack.java
 *
 * Created on November 2, 2005, 5:25 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package cz.pcland.knapsack;

import cz.pcland.ga.BaseIndividual;
import cz.pcland.ga.BinaryIndividual;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import cz.pcland.io.*;
import cz.pcland.ga.*;

//import java.io.*;

public class KnapSack implements Loadable{
    public Vector items;
    double capacity = 500;
    public KnapSackPanel pnl = null;
    
    
    public KnapSack(double cap) {
        capacity = cap;
        items = new Vector();
    }
    
    public void loadFromString(String str){
        InputSource inputSource = null;
   
        inputSource = new InputSource(new StringReader(str));

        try {
            XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
            
            org.xml.sax.ContentHandler handler = new KnapSackHandler(this);
            
            org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
            parser.setContentHandler(handler);
            parser.parse(inputSource);
            if(pnl != null){
                pnl.updateKSItemsList();
            }
        } catch (Exception e) {
            System.err.println(e + "error");
        }
        
        
        
    }
    
    public  String saveToFile(){
        StringWriter out = new StringWriter();
        try {/*
        //file = new File("/home/petr/workspace/javabeans/KnapSack4/KnapSack/src/cz/pcland/knapsack/KnapSack.data");
        OutputStream fout= new FileOutputStream(file);
        OutputStream bout= new BufferedOutputStream(fout);
        OutputStreamWriter out = new OutputStreamWriter(bout, "utf8");
         */
            
            out.write("<?xml version=\"1.0\" ");
            out.write("encoding=\"UTF8\"?>\r\n");
            out.write("<knapsack>\r\n");
            
            for(int i = 0; i < this.items.size(); i++) {
                out.write("<item>\r\n");
                out.write("<price>" + ((KnapSackItem)this.items.get(i)).getPrice() + "</price>\r\n");
                out.write("<capacity>" + ((KnapSackItem)this.items.get(i)).getCapacity() + "</capacity>\r\n");
                out.write("</item>\r\n");
                
            }
            out.write("<kscapacity>" + String.valueOf(this.getCapacity()) + "</kscapacity>\r\n");
            out.write("</knapsack>\r\n");
            
            out.flush();  // Don't forget to flush!
            out.close();
            
        }

        
        catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return out.toString();
    }
    
    public void setContent(BaseIndividual str) {
        boolean[] bits = ((BinaryIndividual)str).getString();
        KnapSackItem temp;
        int i = 0;
        
        for(Enumeration e = items.elements();e.hasMoreElements();) {
            temp = (KnapSackItem)e.nextElement();
            temp.removeFromSack();
            if(bits[i]) {
                temp.addToSack();
            }
            i++;
        }
    }
    
    public void setApproximate(BaseIndividual str) {
        boolean[] bits = ((BinaryIndividual)str).getString();
        KnapSackItem temp;
        int i = 0;
        
        for(Enumeration e = items.elements();e.hasMoreElements();) {
            temp = (KnapSackItem)e.nextElement();
            temp.removeFromApproximate();
            if(bits[i]) {
                temp.addToApproximate();
            }
            i++;
        }
    }
    
    public void cleanAllContent() {
        KnapSackItem temp;
        for(Enumeration e = items.elements();e.hasMoreElements();) {
            temp = (KnapSackItem)e.nextElement();
            temp.removeFromSack();
            temp.removeFromApproximate();
        }
    }
    
    public void setCapacity(double cap){
        capacity = cap;
    }
    
    public double getSumOfCapacity(BaseIndividual str){
        boolean[] bits = ((BinaryIndividual)str).getString();
        KnapSackItem temp;
        int i = 0;
        double sum = 0;
        
        for(Enumeration e = items.elements();e.hasMoreElements();) {
            temp = (KnapSackItem)e.nextElement();
            
            if(bits[i]) {
                sum+=temp.getCapacity();
            }
            i++;
        }
        return sum;
    }
    
    public double getCapacity(){
        return capacity;
    }
    
    public void addItem(double price, double capacity) {
        items.add(new KnapSackItem(price, capacity));
    }
    
    public void addItem(KnapSackItem item) {
        items.add(item);
    }
    
    public void addRandom(int count) {
        for(int i=0;i<count;i++){
            int rand1 = Math.abs(MyRand.getInt());
            int rand2 = Math.abs(MyRand.getInt());
            
            if(rand1 == 0.0d || rand2 == 0.0d) System.out.println("rand=0");
           // System.out.println("rand1="  + rand1);
            
            double capacity = (double)((int)((Math.abs(5+rand1%100 - Math.random()))*10.0d))/10.0d;
            double price = (double)((int)((Math.abs(5+rand2%100 - Math.random()))*10.0d))/10.0d;
            
            if(capacity == 0.0d) System.out.println("capacity=0");
            addItem(new KnapSackItem(price,capacity));
        }
    }
    
    
    public int totalItems(){
        return items.size();
    }
    
    public void removeItem(int index) {
        items.remove(index);
    }
    
    public Vector getItems(){
        return items;
    }
    
    public void setItems(Vector items){
        this.items = items;
    }
    
    
    
  /*  public String getInfo(BaseString str) {
        return this.firnessObj.getInfo(str);
    }
   */
    
}

class KnapSackHandler extends DefaultHandler {
    
    private boolean inItem = false;
    private boolean inPrice = false;
    private boolean inCapacity = false;
    private boolean inKSCapacity = false;
    private double capacity = 0;
    private double price = 0;
    boolean priceLoaded = false;
    boolean capacityLoaded = false;
    Vector items;
    KnapSack ks;
    
    public KnapSackHandler(KnapSack ks){
        super();
        this.ks = ks;
        items = new Vector();
    }
    
    public void startElement(String namespaceURI, String localName, String qualifiedName, Attributes atts) throws SAXException {
        
        if(localName.equalsIgnoreCase("item")) inItem = true;
        if(localName.equalsIgnoreCase("price")) inPrice = true;
        if(localName.equalsIgnoreCase("capacity")) inCapacity = true;
        if(localName.equalsIgnoreCase("kscapacity")) inKSCapacity = true;
        //System.out.println(" public void startElement(String namespaceURI=" + namespaceURI + ", String localName="+localName+", String qualifiedName=" + qualifiedName + ", Attributes atts=" + atts + ")");
    }
    
    public void endElement(String namespaceURI, String localName, String qualifiedName) throws SAXException {
        
        if(localName.equalsIgnoreCase("item")) inItem = false;
        if(localName.equalsIgnoreCase("price")) inPrice = false;
        if(localName.equalsIgnoreCase("capacity")) inCapacity = false;
        if(localName.equalsIgnoreCase("kscapacity")) inKSCapacity = false;
        //System.out.println(" public void endElement(String namespaceURI=" + namespaceURI + ", String localName="+localName+", String qualifiedName=" + qualifiedName + ")");
    }
    
    public void endDocument() throws SAXException {
        ks.setItems(this.items);
    }
    
    public void characters(char[] ch, int start, int length) throws SAXException {
        
        if(priceLoaded && capacityLoaded) {
            items.add(new KnapSackItem(price,capacity));
            priceLoaded = false;
            capacityLoaded = false;
        }
        
        if(inItem) {
            
            if(inPrice){
                String tmp = "";
                for (int i = start; i < start+length; i++) {
                    tmp += ch[i];
                }
                price = Double.parseDouble(tmp);
                priceLoaded = true;
            }
            
            if(inCapacity){
                String tmp = "";
                for (int i = start; i < start+length; i++) {
                    tmp += ch[i];
                }
                capacity = Double.parseDouble(tmp);
                capacityLoaded = true;
            }
            
        }else {
            if(inKSCapacity) {
                String tmp = "";
                for (int i = start; i < start+length; i++) {
                    tmp += ch[i];
                }
                System.out.println("capacity str=" + tmp);
                capacity = Double.parseDouble(tmp);
                System.out.println("capacity double=" + capacity);
                ks.setCapacity(capacity);
            }
        }
        
        
    }
    
    
}
