package ee.ut.ga.business;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import ee.ut.ga.model.Coordinate;
import ee.ut.ga.model.PWM;
import ee.ut.ga.model.Weight;
import ee.ut.ga.util.DataLoaderUtil;
import ee.ut.ga.util.PropertyUtil;

public class RocGraph {
  
  public static void createROC(String propPath) throws Exception {
    Properties properties = PropertyUtil.loadProperties(propPath);
    
    String PAM_TO_ANALIZE = properties.getProperty(PropertyUtil.PAM_TO_ANALIZE);
    String PAM_RESULT = properties.getProperty(PropertyUtil.PAM_RESULT);
    
    Map priors = PropertyUtil.loadPriors(properties);
    Map data = DataLoaderUtil.loadData(properties.getProperty(PropertyUtil.DATASET));
    List population = DataLoaderUtil.loadInitialPopulation(PAM_TO_ANALIZE, priors);
    
    PWM pwm = (PWM) population.get(0);
    int goodAll = pwm.getDataGoodAll();
    
    if (goodAll == 0)
      throw new Exception("PAM properties in file " + PAM_TO_ANALIZE + " must contain goodAll prop!");

    List coordinates = new ArrayList();
    BigDecimal area = new BigDecimal("0");
    
    List weights = FitnessFunction.calculateAllWeights(data, pwm);
    Collections.sort(weights);
    
    BigDecimal x_step = new BigDecimal(1.0/(weights.size()-goodAll));
    BigDecimal y_step = new BigDecimal(1.0/goodAll);
    
    BigDecimal current_x = new BigDecimal("0").setScale(4, BigDecimal.ROUND_HALF_UP);
    BigDecimal current_y = new BigDecimal("0").setScale(4, BigDecimal.ROUND_HALF_UP);
    coordinates.add(new Coordinate(current_x, current_y));
    
    BigDecimal prev_x = current_x;
    BigDecimal prev_y = current_y;
    
    for (Iterator i = weights.iterator(); i.hasNext();) {
      Weight currentWeight = (Weight) i.next();
      if (currentWeight.getDataRow() >= goodAll) {
        current_x = prev_x.add(x_step);
        current_y = prev_y;
      } else {
        current_x = prev_x;
        current_y = prev_y.add(y_step);
        area = area.add((new BigDecimal("1").subtract(current_x)).multiply(current_y.subtract(prev_y)));
      }
      
      coordinates.add(new Coordinate(current_x.setScale(4, BigDecimal.ROUND_HALF_UP), current_y.setScale(4, BigDecimal.ROUND_HALF_UP)));
      prev_x = current_x;
      prev_y = current_y;
    }
    
    StringBuffer result = new StringBuffer();
    result.append(pwm.toString());
    result.append("# THE AREA IS ").append(area.setScale(6, BigDecimal.ROUND_HALF_UP)).append("\n");
    result.append(">coordinates").append("\n");
    StringBuffer resultCoordinates = new StringBuffer();
    for (Iterator i = coordinates.iterator(); i.hasNext();) {
      Coordinate coordinate = (Coordinate) i.next();
      resultCoordinates.append(coordinate.getX()).append("\t").append(coordinate.getY()).append("\n");
    }
    result.append(resultCoordinates.toString().replaceAll("\\.", ","));
    
    System.out.println(result);
    
    DataLoaderUtil.writeResult(result.toString(), PAM_RESULT, false);
  }
}
