/*
 * The Broad Institute
 * SOFTWARE COPYRIGHT NOTICE AGREEMENT
 * This is copyright (2007-2008) by the Broad Institute/Massachusetts Institute 
 * of Technology.  It is licensed to You under the Gnu Public License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *    http://www.opensource.org/licenses/gpl-2.0.php
 *
 * This software is supplied without any warranty or guaranteed support
 * whatsoever. Neither the Broad Institute nor MIT can be responsible for its
 * use, misuse, or functionality.
*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.broad.igv.data;

import java.util.Collection;
import org.broad.igv.feature.Genome;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author jrobinso
 */
public class GenomeSummaryData {

    // TODO -- remove hardocded unit value. 
    long locationUnit = 1000;
    // TODO -- compute this from dataset size
    int samplingFreq = -1;
    Genome genome;
    /**
     * Map of chromosomes -> locaction arrays
     */
    Map<String, long[]> locationMap = new HashMap();
    /**
     * Map of chromosomes ->  data maps, each of which maps sample headings
     * to data arrays.
     */
    Map<String, Map<String, float[]>> dataMap = new HashMap();
    int[] locations;

    public GenomeSummaryData(Genome genome) {
        this.genome = genome;
    }
    
    public void setSamplingFreq(int freq) {
        this.samplingFreq = freq;
    }

    /**
     * Set sampling freq to result in ~1000 data points per chromosome
     * @param totalSize
     * @return
     */
    private int getSamplingFreq(int totalSize) {
        if (samplingFreq < 0) {
            samplingFreq = Math.max(1, totalSize / 100000);
        }
        return samplingFreq;
    }

    public void addLocations(String chr, int[] chrLocations) {
        int freq = getSamplingFreq(chrLocations.length);
        int len = Math.max(1, chrLocations.length / freq);
        long[] genomeLocations = new long[len];
        for (int i = 0; i < genomeLocations.length; i++) {
            genomeLocations[i] = chrLocations[i * freq];
        }
        locationMap.put(chr, genomeLocations);
    }

    public void addData(String sample, String chr, float[] data) {
        int freq = getSamplingFreq(data.length);
        int len = Math.max(1, data.length / freq);
        float[] genomeData = new float[len];
        for (int i = 0; i < genomeData.length; i++) {
            genomeData[i] = data[i * freq];
        }

        Map<String, float[]> tmp = dataMap.get(sample);
        if (tmp == null) {
            tmp = new HashMap();
            dataMap.put(sample, tmp);
        }
        tmp.put(chr, genomeData);
    }

    public int[] getLocations() {
        if (locations == null) {
            Collection<String> chrNames = genome.getChromosomeNames();
            int nPts = 0;
            for (String chr : chrNames) {
                long[] chrLocs = locationMap.get(chr);
                if (chrLocs != null) {
                    nPts += chrLocs.length;
                }
            }
            locations = new int[nPts];

            int index = 0;
            long offset = 0;
            for (String chr : chrNames) {
                long[] chrLocs = locationMap.get(chr);
                if (chrLocs != null) {
                    for (int i = 0; i < chrLocs.length; i++) {
                        locations[index] = (int) ((offset + chrLocs[i]) / locationUnit);
                        if (locations[index] < 0) {
                            System.out.println("Negative location");
                        }
                        index++;
                    }
                }
                offset += genome.getChromosome(chr).getLength();
            }
        }
        return locations;
    }

    public float[] getData(String heading) {

        int nPts = getLocations().length;
        float[] data = new float[nPts];

        Collection<String> chrNames = genome.getChromosomeNames();

        int index = 0;
        for (String chr : chrNames) {
            if (dataMap.containsKey(heading)) {
                float[] chrData = dataMap.get(heading).get(chr);
                if (chrData != null) {
                    for (int i = 0; i < chrData.length; i++) {
                        data[index] = chrData[i];
                        index++;
                    }
                }
            }
        }
        return data;

    }
}
