/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package plots;

import com.sun.j3d.utils.applet.MainFrame;
import java.awt.Frame;
import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * @author Adam
 */
public class ArrangePlotValues {
   
    private PlotPyramid _plotPyramidInstance = null;
    //_axes is arranged as close, other, query
    
    private ArrayList<ArrayList<Float>> _axes = new ArrayList<ArrayList<Float>>();
    
    private ArrayList<Float> _closeAxisX = new ArrayList<Float>();
    private ArrayList<Float> _closeAxisY = new ArrayList<Float>();
    private ArrayList<Float> _closeAxisZ = new ArrayList<Float>();
    
    private ArrayList<Float> _otherAxisX = new ArrayList<Float>();
    private ArrayList<Float> _otherAxisY = new ArrayList<Float>();
    private ArrayList<Float> _otherAxisZ = new ArrayList<Float>();
    
    private ArrayList<Float> _queryAxisX = new ArrayList<Float>();
    private ArrayList<Float> _queryAxisY = new ArrayList<Float>();
    private ArrayList<Float> _queryAxisZ = new ArrayList<Float>();
    
    
    private float _maxX, _maxY, _maxZ;
    private float _minX, _minY, _minZ;
    private float absMax;
    private float _scaleFactor = 100.0f;
    private float _scaleVal = 80.0f; //this is a hack. needs to be better.
    private float _medianVals[];
    private int _plotClose;
    private int _plotQuery;
    
    public ArrangePlotValues(ArrayList<double []> plotList, int showClose, int showQuery)
    {
        this._plotClose = showClose;
        this._plotQuery = showQuery;
        parseText(plotList);
    }
            
    
    public void parseText(ArrayList<double[]> plotList)
    {
        try{

        //as of now, plotlist's indices are considered: close, other, query
        
         extractAxes(plotList);
         _medianVals = findMedianVals(_queryAxisX, _queryAxisY, _queryAxisZ,
                                                            _closeAxisZ, _closeAxisY, _closeAxisZ);
        
        /*FIXXXXX
       _maxX = getMax(_closeAxisX); //gets max and min values of each axis
       _maxY = getMax(_closeAxisY);
       _maxZ = getMax(_closeAxisZ);
       
       _minX = getMin(_closeAxisX);
       _minY = getMin(_closeAxisY);
       _minZ = getMin(_closeAxisZ);
       
       _maxX = getMax(_otherAxisX); //gets max and min values of each axis
       _maxY = getMax(_otherAxisY);
       _maxZ = getMax(_otherAxisZ);
       
       _minX = getMin(_otherAxisX);
       _minY = getMin(_otherAxisY);
       _minZ = getMin(_otherAxisZ);
       
       _maxX = getMax(_queryAxisX); //gets max and min values of each axis
       _maxY = getMax(_queryAxisY);
       _maxZ = getMax(_queryAxisZ);
       
       _minX = getMin(_queryAxisX);
       _minY = getMin(_queryAxisY);
       _minZ = getMin(_queryAxisZ);
         **/
       
       float[] pointsToEval = {_maxX, _maxY, _maxZ, _minX, _minY, _minZ};
       
       //absMax = getResizeValue(pointsToEval); //FIX!
       
       _axes.add(_closeAxisX);
       _axes.add(_otherAxisX);
       _axes.add(_queryAxisX);
       _axes.add(_closeAxisY);
       _axes.add(_otherAxisY);
       _axes.add(_queryAxisY);
       _axes.add(_closeAxisZ);
       _axes.add(_otherAxisZ);
       _axes.add(_queryAxisZ);
       
       System.out.println("The max abs value is: "+absMax);
       
         System.out.println("wee");
       
       // Frame frame = new com.sun.j3d.utils.applet.MainFrame(new PlotPyramid(_axes, absMax), 800, 800);
            setPlotPyramidInstance(new PlotPyramid(_axes, absMax, _medianVals));
        
        }catch(Exception e){
            //System.out.println("Problem reading files.");
            e.printStackTrace();
        }       
    }

    
    private void addValToAxisList(double[] list, String toPlot)
    {
         //NOTE: for now, only using "query" axis, also 0 , 1 , 2 is x ,y, z axes
        System.out.println("At index 0: " + list[0]);
        System.out.println("At index 1: " + list[1]);
        System.out.println("At index 2: " + list[2]);
        
        float x = (float)list[0] * _scaleVal;
        float y = (float)list[1] * _scaleVal;
        float z = (float)list[2] * _scaleVal;
        
        float newXVal = x;
        float newYVal = y;
        float newZVal = z;
        
        if(toPlot.equalsIgnoreCase("close"))
        {
            _closeAxisX.add(newXVal);
            _closeAxisY.add(newYVal);
            _closeAxisZ.add(newZVal);
        }else if(toPlot.equalsIgnoreCase("query"))
        {
            _queryAxisX.add(newXVal);
            _queryAxisY.add(newYVal);
            _queryAxisZ.add(newZVal);       
        }
    }
   
    private float[] findMedianVals(ArrayList<Float>_queryAxisX, ArrayList<Float> _queryAxisY, ArrayList<Float> _queryAxisZ,
                                                         ArrayList<Float>_closeAxisX, ArrayList<Float> _closeAxisY, ArrayList<Float> _closeAxisZ)
    {
        float[] medVals = new float[6];
        
        Collections.sort(_queryAxisX);
        Collections.sort(_queryAxisY);
        Collections.sort(_queryAxisZ);
        
        if(_queryAxisX.size() > 0 && _queryAxisY.size() > 0 && _queryAxisZ.size() > 0)
        {
                if(_queryAxisX.size() % 2 != 0 && _queryAxisX.size() > 0)
                {
                    medVals[0] = _queryAxisX.get((((_queryAxisX.size()/2)-1) + (_queryAxisX.size()/2)+1) / 2);
                }else{
                    medVals[0] = _queryAxisX.get(_queryAxisX.size()/2);
                }

                if(_queryAxisY.size() % 2 != 0 && _queryAxisY.size() > 0)
                {
                    medVals[1] = _queryAxisY.get((((_queryAxisY.size()/2)-1) + (_queryAxisY.size()/2)+1) / 2);
                }else{
                    medVals[1] = _queryAxisY.get(_queryAxisY.size()/2);
                }

                if(_queryAxisZ.size() % 2 != 0)
                {         
                        medVals[2] = _queryAxisZ.get((((_queryAxisZ.size()/2)-1) + (_queryAxisZ.size()/2)+1) / 2);
                }else{
                    medVals[2] = _queryAxisZ.get(_queryAxisZ.size()/2);
                }
            }
        
           if(_closeAxisX.size() > 0 && _closeAxisY.size() > 0 && _closeAxisZ.size() > 0)
            {
                if(_closeAxisX.size() % 2 != 0 && _closeAxisX.size() > 0)
                {
                    medVals[3] = _closeAxisX.get((((_closeAxisX.size()/2)-1) + (_closeAxisX.size()/2)+1) / 2);
                }else{
                    medVals[3] = _closeAxisX.get(_closeAxisX.size()/2);
                }

                if(_closeAxisY.size() % 2 != 0 && _closeAxisY.size() > 0)
                {
                    medVals[4] = _closeAxisY.get((((_closeAxisY.size()/2)-1) + (_closeAxisY.size()/2)+1) / 2);
                }else{
                    medVals[4] = _closeAxisY.get(_closeAxisY.size()/2);
                }

                if(_closeAxisZ.size() % 2 != 0)
                {         
                        medVals[5] = _closeAxisZ.get((((_closeAxisZ.size()/2)-1) + (_closeAxisZ.size()/2)+1) / 2);
                }else{
                    medVals[5] = _closeAxisZ.get(_closeAxisZ.size()/2);
                }
            }
            return medVals;        
    }
    
    private void extractAxes(ArrayList<double[]> plotList)
    {
        
        System.out.println("Plotlist size: " + plotList.size());
        
        int closeIndex = 0;
        int queryIndex = 1;
                
        if (_plotClose == 1 && plotList.size() >= 1)
            addValToAxisList(plotList.get(0), "close");
        
        if(_plotQuery == 1 && plotList.size() >= 2)
            addValToAxisList(plotList.get(1), "query");
        
        
        /*
        for(double[] doubleArray : plotList)
        {
            addValToAxisList(doubleArray);
            System.out.println("Added array");
        }
         * */
    }
    
    private float getMin(ArrayList<Float> axis)
    {
        float min = 0;
        
        for(int i = 0; i < axis.size(); i++)
        {
            if(i == 0){min = axis.get(i);}
            if(axis.get(i) < min)
            {
                min = axis.get(i);
            }
        }      
        return min;
    }
    
    private float getMax(ArrayList<Float> axis)
    {
         float max = 0;
        
        for(int i = 0; i < axis.size(); i++)
        {
            if(i == 0){max = axis.get(i);}
            if(axis.get(i) > max)
            {
                max = axis.get(i);
            }
        }
        return max;
    }
    
    
    private float getCubeMultiple(float min, float max)
    {
      return 2/(max-min);  
    }
    
    
    
    public static void main(String[] args)
    {
        ArrayList<double[]> plotList = null;
        new ArrangePlotValues(plotList, 1, 1);
    }

    public PlotPyramid getPlotPyramidInstance() {
        return _plotPyramidInstance;
    }

    public void setPlotPyramidInstance(PlotPyramid plotPyramidInstance) {
        this._plotPyramidInstance = plotPyramidInstance;
    }

    public float[] getMedianVals() {
        return _medianVals;
    }
}
