package jp.crestmuse.cmx.amusaj.filewrappers;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.LinkedList;
import java.util.zip.GZIPOutputStream;

import org.xml.sax.SAXException;

import jp.crestmuse.cmx.filewrappers.FileWrapperCompatible;

public class ArffWrapper implements FileWrapperCompatible {
  
  private String fileName;
  private String relation;
  private LinkedList<Attribute> attributelist;
  private LinkedList<String> datalist;
  
  public ArffWrapper(String relation){
    fileName = null;
    this.relation = relation;
    attributelist = new LinkedList<Attribute>();
    datalist = new LinkedList<String>();
  }
  
  public void addAttribute(String name, String[] nominals){
    attributelist.add(new Attribute(name, nominals));
  }
  
  public void addData(String data){
    datalist.add(data);
  }

  public String getFileName() {
    return fileName;
  }

  public void write(OutputStream out) throws IOException, SAXException {
    out.write(("@relation " + relation + System.getProperty("line.separator") + System.getProperty("line.separator")).getBytes());
    for(Attribute a : attributelist)
      out.write((a.toString() + System.getProperty("line.separator")).getBytes());
    out.write((System.getProperty("line.separator") + "@data" + System.getProperty("line.separator")).getBytes());
    for(String s : datalist) out.write((s + System.getProperty("line.separator")).getBytes());
  }

  public void write(Writer writer) throws IOException, SAXException {
    throw new UnsupportedOperationException();
  }

  public void writefile(File file) throws IOException, SAXException {
    write(new BufferedOutputStream(new FileOutputStream(file)));
  }
  
  public void writeGZippedFile(File file) throws IOException, SAXException {
    write(new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
  }
  
  class Attribute{
    Attribute(String name, String[] nominals){
      this.name = name;
      this.nominals = nominals;
      this.isNominal = true;
    }
    Attribute(String name, double numeric){
      this.name = name;
      this.numeric = numeric;
      this.isNominal = false;
    }
    public String toString(){
      String result = "@attribute " + name + " ";
      if(isNominal){
        result += "{";
        for(String s : nominals) result += s + ", ";
        result +="}";
      }else{
        result += numeric;
      }
      return result;
    }
    private String name;
    private boolean isNominal;
    private String[] nominals;
    private double numeric;
  }

}
