/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.test.tilebenchmark;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;

import com.test.tilebenchmark.RunData.TileData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class PlaybackGraphs {
    private static final int BAR_WIDTH = PlaybackView.TILE_SCALE * 3;
    private static final float CANVAS_SCALE = 0.2f;
    private static final double IDEAL_FRAMES = 60;
    private static final int LABELOFFSET = 100;
    private static Paint whiteLabels;

    private static double viewportCoverage(TileData view, TileData tile) {
        if (tile.left < (view.right * view.scale)
                && tile.right >= (view.left * view.scale)
                && tile.top < (view.bottom * view.scale)
                && tile.bottom >= (view.top * view.scale)) {
            return 1.0f;
        }
        return 0.0f;
    }

    protected interface MetricGen {
        public double getValue(TileData[] frame);

        public double getMax();

        public int getLabelId();
    };

    protected static MetricGen[] Metrics = new MetricGen[] {
            new MetricGen() {
                // framerate graph
                @Override
                public double getValue(TileData[] frame) {
                    int renderTimeUS = frame[0].level;
                    return 1.0e6f / renderTimeUS;
                }

                @Override
                public double getMax() {
                    return IDEAL_FRAMES;
                }

                @Override
                public int getLabelId() {
                    return R.string.frames_per_second;
                }
            }, new MetricGen() {
                // coverage graph
                @Override
                public double getValue(TileData[] frame) {
                    double total = 0, totalCount = 0;
                    for (int tileID = 1; tileID < frame.length; tileID++) {
                        TileData data = frame[tileID];
                        double coverage = viewportCoverage(frame[0], data);
                        total += coverage * (data.isReady ? 100 : 0);
                        totalCount += coverage;
                    }
                    if (totalCount == 0) {
                        return -1;
                    }
                    return total / totalCount;
                }

                @Override
                public double getMax() {
                    return 100;
                }

                @Override
                public int getLabelId() {
                    return R.string.viewport_coverage;
                }
            }
    };

    protected interface StatGen {
        public double getValue(double sortedValues[]);

        public int getLabelId();
    }

    public static double getPercentile(double sortedValues[], double ratioAbove) {
        if (sortedValues.length == 0)
            return -1;

        double index = ratioAbove * (sortedValues.length - 1);
        int intIndex = (int) Math.floor(index);
        if (index == intIndex) {
            return sortedValues[intIndex];
        }
        double alpha = index - intIndex;
        return sortedValues[intIndex] * (1 - alpha)
                + sortedValues[intIndex + 1] * (alpha);
    }

    public static double getMean(double sortedValues[]) {
        if (sortedValues.length == 0)
            return -1;

        double agg = 0;
        for (double val : sortedValues) {
            agg += val;
        }
        return agg / sortedValues.length;
    }

    public static double getStdDev(double sortedValues[]) {
        if (sortedValues.length == 0)
            return -1;

        double agg = 0;
        double sqrAgg = 0;
        for (double val : sortedValues) {
            agg += val;
            sqrAgg += val*val;
        }
        double mean = agg / sortedValues.length;
        return Math.sqrt((sqrAgg / sortedValues.length) - (mean * mean));
    }

    protected static StatGen[] Stats = new StatGen[] {
            new StatGen() {
                @Override
                public double getValue(double[] sortedValues) {
                    return getPercentile(sortedValues, 0.25);
                }

                @Override
                public int getLabelId() {
                    return R.string.percentile_25;
                }
            }, new StatGen() {
                @Override
                public double getValue(double[] sortedValues) {
                    return getPercentile(sortedValues, 0.5);
                }

                @Override
                public int getLabelId() {
                    return R.string.percentile_50;
                }
            }, new StatGen() {
                @Override
                public double getValue(double[] sortedValues) {
                    return getPercentile(sortedValues, 0.75);
                }

                @Override
                public int getLabelId() {
                    return R.string.percentile_75;
                }
            }, new StatGen() {
                @Override
                public double getValue(double[] sortedValues) {
                    return getStdDev(sortedValues);
                }

                @Override
                public int getLabelId() {
                    return R.string.std_dev;
                }
            }, new StatGen() {
                @Override
                public double getValue(double[] sortedValues) {
                    return getMean(sortedValues);
                }

                @Override
                public int getLabelId() {
                    return R.string.mean;
                }
            },
    };

    public PlaybackGraphs() {
        whiteLabels = new Paint();
        whiteLabels.setColor(Color.WHITE);
        whiteLabels.setTextSize(PlaybackView.TILE_SCALE / 3);
    }

    private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>();
    protected final double[][] mStats = new double[Metrics.length][Stats.length];
    protected HashMap<String, Double> mSingleStats;

    private void gatherFrameMetric(int metricIndex, double metricValues[], RunData data) {
        // create graph out of rectangles, one per frame
        int lastBar = 0;
        for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
            TileData frame[] = data.frames[frameIndex];
            int newBar = (int)((frame[0].top + frame[0].bottom) * frame[0].scale / 2.0f);

            MetricGen s = Metrics[metricIndex];
            double absoluteValue = s.getValue(frame);
            double relativeValue = absoluteValue / s.getMax();
            relativeValue = Math.min(1,relativeValue);
            relativeValue = Math.max(0,relativeValue);
            int rightPos = (int) (-BAR_WIDTH * metricIndex);
            int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue));

            ShapeDrawable graphBar = new ShapeDrawable();
            graphBar.getPaint().setColor(Color.BLUE);
            graphBar.setBounds(leftPos, lastBar, rightPos, newBar);

            mShapes.add(graphBar);
            metricValues[frameIndex] = absoluteValue;
            lastBar = newBar;
        }
    }

    public void setData(RunData data) {
        mShapes.clear();
        double metricValues[] = new double[data.frames.length];

        mSingleStats = data.singleStats;

        if (data.frames.length == 0) {
            return;
        }

        for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
            // calculate metric based on list of frames
            gatherFrameMetric(metricIndex, metricValues, data);

            // store aggregate statistics per metric (median, and similar)
            Arrays.sort(metricValues);
            for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
                mStats[metricIndex][statIndex] =
                        Stats[statIndex].getValue(metricValues);
            }
        }
    }

    public void drawVerticalShiftedShapes(Canvas canvas,
            ArrayList<ShapeDrawable> shapes) {
        // Shapes drawn here are drawn relative to the viewRect
        Rect viewRect = shapes.get(shapes.size() - 1).getBounds();
        canvas.translate(0, 5 * PlaybackView.TILE_SCALE - viewRect.top);

        for (ShapeDrawable shape : mShapes) {
            shape.draw(canvas);
        }
        for (ShapeDrawable shape : shapes) {
            shape.draw(canvas);
        }
    }

    public void draw(Canvas canvas, ArrayList<ShapeDrawable> shapes,
            ArrayList<String> strings, Resources resources) {
        canvas.scale(CANVAS_SCALE, CANVAS_SCALE);

        canvas.translate(BAR_WIDTH * Metrics.length, 0);

        canvas.save();
        drawVerticalShiftedShapes(canvas, shapes);
        canvas.restore();

        for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
            String label = resources.getString(
                    Metrics[metricIndex].getLabelId());
            int xPos = (metricIndex + 1) * -BAR_WIDTH;
            int yPos = LABELOFFSET;
            canvas.drawText(label, xPos, yPos, whiteLabels);
            for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
                String statLabel = resources.getString(
                        Stats[statIndex].getLabelId()).substring(0,3);
                label = statLabel + " " + resources.getString(
                        R.string.format_stat, mStats[metricIndex][statIndex]);
                yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE
                        / 2;
                canvas.drawText(label, xPos, yPos, whiteLabels);
            }
        }
        for (int stringIndex = 0; stringIndex < strings.size(); stringIndex++) {
            int yPos = LABELOFFSET + stringIndex * PlaybackView.TILE_SCALE / 2;
            canvas.drawText(strings.get(stringIndex), 0, yPos, whiteLabels);
        }
    }
}
