/*
 * Copyright (C) 2014 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 org.drrickorang.loopback;

import java.util.Arrays;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Scroller;


/**
 * This view is the wave plot shows on the main activity.
 */

public class WavePlotView extends View  {
    private static final String TAG = "WavePlotView";

    private double [] mBigDataArray;
    private double [] mValuesArray;  //top points to plot
    private double [] mValuesArray2; //bottom

    private double [] mInsetArray;
    private double [] mInsetArray2;
    private int       mInsetSize = 20;

    private double mZoomFactorX = 1.0; //1:1  1 sample / point .  Note: Point != pixel.
    private int    mCurrentOffset = 0;
    private int    mArraySize = 100; //default size
    private int    mSamplingRate;

    private GestureDetector        mDetector;
    private ScaleGestureDetector   mSGDetector;
    private MyScaleGestureListener mSGDListener;
    private Scroller mScroller;

    private int mWidth;
    private int mHeight;
    private boolean mHasDimensions;

    private Paint mMyPaint;
    private Paint mPaintZoomBox;
    private Paint mPaintInsetBackground;
    private Paint mPaintInsetBorder;
    private Paint mPaintInset;
    private Paint mPaintGrid;
    private Paint mPaintGridText;

    // Default values used when we don't have a valid waveform to display.
    // This saves us having to add multiple special cases to handle null waveforms.
    private int mDefaultSampleRate = 48000; // chosen because it is common in real world devices
    private double[] mDefaultDataVector = new double[mDefaultSampleRate]; // 1 second of fake audio

    public WavePlotView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mSGDListener = new MyScaleGestureListener();
        mDetector = new GestureDetector(context, new MyGestureListener());
        mSGDetector = new ScaleGestureDetector(context, mSGDListener);
        mScroller = new Scroller(context, new LinearInterpolator(), true);
        initPaints();

        // Initialize the value array to 1s silence
        mSamplingRate = mDefaultSampleRate;
        mBigDataArray = new double[mSamplingRate];
        Arrays.fill(mDefaultDataVector, 0);
    }


    /** Initiate all the Paint objects. */
    private void initPaints() {
        final int COLOR_WAVE = 0xFF1E4A99;
        final int COLOR_ZOOM_BOX = 0X50E0E619;
        final int COLOR_INSET_BACKGROUND = 0xFFFFFFFF;
        final int COLOR_INSET_BORDER = 0xFF002260;
        final int COLOR_INSET_WAVE = 0xFF910000;
        final int COLOR_GRID = 0x7F002260;
        final int COLOR_GRID_TEXT = 0xFF002260;

        mMyPaint = new Paint();
        mMyPaint.setColor(COLOR_WAVE);
        mMyPaint.setAntiAlias(true);
        mMyPaint.setStyle(Style.FILL_AND_STROKE);
        mMyPaint.setStrokeWidth(1);

        mPaintZoomBox = new Paint();
        mPaintZoomBox.setColor(COLOR_ZOOM_BOX);
        mPaintZoomBox.setAntiAlias(true);
        mPaintZoomBox.setStyle(Style.FILL);

        mPaintInsetBackground = new Paint();
        mPaintInsetBackground.setColor(COLOR_INSET_BACKGROUND);
        mPaintInsetBackground.setAntiAlias(true);
        mPaintInsetBackground.setStyle(Style.FILL);

        mPaintInsetBorder = new Paint();
        mPaintInsetBorder.setColor(COLOR_INSET_BORDER);
        mPaintInsetBorder.setAntiAlias(true);
        mPaintInsetBorder.setStyle(Style.STROKE);
        mPaintInsetBorder.setStrokeWidth(1);

        mPaintInset = new Paint();
        mPaintInset.setColor(COLOR_INSET_WAVE);
        mPaintInset.setAntiAlias(true);
        mPaintInset.setStyle(Style.FILL_AND_STROKE);
        mPaintInset.setStrokeWidth(1);

        final int textSize = 25;
        mPaintGrid = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintGrid.setColor(COLOR_GRID); //gray
        mPaintGrid.setTextSize(textSize);

        mPaintGridText = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintGridText.setColor(COLOR_GRID_TEXT); //BLACKgray
        mPaintGridText.setTextSize(textSize);
    }

    public double getZoom() {
        return mZoomFactorX;
    }


    /** Return max zoom out value (> 1.0)/ */
    public double getMaxZoomOut() {
        double maxZoom = 1.0;

        if (mBigDataArray != null) {
            int n = mBigDataArray.length;
            maxZoom = ((double) n) / mArraySize;
        }

        return maxZoom;
    }


    public double getMinZoomOut() {
        double minZoom = 1.0;
        return minZoom;
    }


    public int getOffset() {
        return mCurrentOffset;
    }


    public void setZoom(double zoom) {
        double newZoom = zoom;
        double maxZoom = getMaxZoomOut();
        double minZoom = getMinZoomOut();

        //foolproof:
        if (newZoom < minZoom)
            newZoom = minZoom;

        if (newZoom > maxZoom)
            newZoom = maxZoom;

        mZoomFactorX = newZoom;
        //fix offset if this is the case
        setOffset(0, true); //just touch offset in case it needs to be fixed.
    }


    public void setOffset(int sampleOffset, boolean relative) {
        int newOffset = sampleOffset;

        if (relative) {
            newOffset = mCurrentOffset + sampleOffset;
        }

        if (mBigDataArray != null) {
            int n = mBigDataArray.length;
            //update offset if last sample is more than expected
            int lastSample = newOffset + (int)getWindowSamples();
            if (lastSample >= n) {
                int delta = lastSample - n;
                newOffset -= delta;
            }

            if (newOffset < 0)
                newOffset = 0;

            if (newOffset >= n)
                newOffset = n - 1;

            mCurrentOffset = newOffset;
        }
    }


    public double getWindowSamples() {
        //samples in current window
        double samples = 0;
        if (mBigDataArray != null) {
            double zoomFactor = getZoom();
            samples = mArraySize * zoomFactor;
        }

        return samples;
    }


    public void refreshGraph() {
        computeViewArray(mZoomFactorX, mCurrentOffset);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mWidth = w;
        mHeight = h;
        log("New w: " + mWidth + " h: " + mHeight);
        mHasDimensions = true;
        initView();
        refreshView();
    }


    private void initView() {
        //re init graphical elements
        mArraySize = mWidth;
        mInsetSize = mWidth / 5;
        mValuesArray = new double[mArraySize];
        mValuesArray2 = new double[mArraySize];
        Arrays.fill(mValuesArray, 0);
        Arrays.fill(mValuesArray2, 0);

        //inset
        mInsetArray = new double[mInsetSize];
        mInsetArray2 = new double[mInsetSize];
        Arrays.fill(mInsetArray, (double) 0);
        Arrays.fill(mInsetArray2, (double) 0);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        boolean showGrid = true;
        boolean showInset = true;

        int i;
        int w = getWidth();
        int h = getHeight();

        double valueMax = 1.0;
        double valueMin = -1.0;
        double valueRange = valueMax - valueMin;

        //print gridline time in ms/seconds, etc.
        if (showGrid) {
            //current number of samples in display
            double samples = getWindowSamples();
            if (samples > 0.0 && mSamplingRate > 0) {
                double windowMs = (1000.0 * samples) / mSamplingRate;

                //decide the best units: ms, 10ms, 100ms, 1 sec, 2 sec
                double msPerDivision = windowMs / 10;
                log(" windowMS: " + windowMs + " msPerdivision: " + msPerDivision);

                int divisionInMS = 1;
                //find the best level for markings:
                if (msPerDivision <= 5) {
                    divisionInMS = 1;
                } else if (msPerDivision < 15) {
                    divisionInMS = 10;
                } else if (msPerDivision < 30) {
                    divisionInMS = 20;
                } else if (msPerDivision < 60) {
                    divisionInMS = 40;
                } else if (msPerDivision < 150) {
                    divisionInMS = 100;
                } else if (msPerDivision < 400) {
                    divisionInMS = 200;
                } else if (msPerDivision < 750) {
                    divisionInMS = 500;
                } else {
                    divisionInMS = 1000;
                }
                log(" chosen Division in MS: " + divisionInMS);

                //current offset in samples
                int currentOffsetSamples = getOffset();
                double currentOffsetMs = (1000.0 * currentOffsetSamples) / mSamplingRate;
                int gridCount = (int) ((currentOffsetMs + divisionInMS) / divisionInMS);
                double startGridCountFrac = ((currentOffsetMs) % divisionInMS);
                log(" gridCount:" + gridCount + " fraction: " + startGridCountFrac +
                    "  firstDivision: " + gridCount * divisionInMS);

                double currentGridMs = divisionInMS - startGridCountFrac; //in mS
                while (currentGridMs <= windowMs) {
                    float newX = (float) (w * currentGridMs / windowMs);
                    canvas.drawLine(newX, 0, newX, h, mPaintGrid);

                    double currentGridValueMS = gridCount * divisionInMS;
                    String label = String.format("%.0f ms", (float) currentGridValueMS);

                    //path
                    Path myPath = new Path();
                    myPath.moveTo(newX, h);
                    myPath.lineTo(newX, h / 2);

                    canvas.drawTextOnPath(label, myPath, 10, -3, mPaintGridText);

                    //advance
                    currentGridMs += divisionInMS;
                    gridCount++;
                }

                //horizontal line
                canvas.drawLine(0, h / 2, w, h / 2, mPaintGrid);
            }
        }

        float deltaX = (float) w / mArraySize;

        //top
        Path myPath = new Path();
        myPath.moveTo(0, h / 2); //start

        if (mBigDataArray != null) {
            if (getZoom() >= 2) {
                for (i = 0; i < mArraySize; ++i) {
                    float top = (float) ((valueMax - mValuesArray[i]) / valueRange) * h;
                    float bottom = (float) ((valueMax - mValuesArray2[i]) / valueRange) * h + 1;
                    float left = i * deltaX;
                    canvas.drawRect(left, top, left + deltaX, bottom, mMyPaint);
                }
            } else {
                for (i = 0; i < (mArraySize - 1); ++i) {
                    float first = (float) ((valueMax - mValuesArray[i]) / valueRange) * h;
                    float second = (float) ((valueMax - mValuesArray[i + 1]) / valueRange) * h;
                    float left = i * deltaX;
                    canvas.drawLine(left, first, left + deltaX, second, mMyPaint);
                }
            }


            if (showInset) {
                float iW = (float) (w * 0.2);
                float iH = (float) (h * 0.2);
                float iX = (float) (w * 0.7);
                float iY = (float) (h * 0.1);
                //x, y of inset
                canvas.drawRect(iX, iY, iX + iW, iY + iH, mPaintInsetBackground);
                canvas.drawRect(iX - 1, iY - 1, iX + iW + 2, iY + iH + 2, mPaintInsetBorder);
                //paintInset
                float iDeltaX = (float) iW / mInsetSize;

                for (i = 0; i < mInsetSize; ++i) {
                    float top = iY + (float) ((valueMax - mInsetArray[i]) / valueRange) * iH;
                    float bottom = iY +
                            (float) ((valueMax - mInsetArray2[i]) / valueRange) * iH + 1;
                    float left = iX + i * iDeltaX;
                    canvas.drawRect(left, top, left + deltaX, bottom, mPaintInset);
                }

                if (mBigDataArray != null) {
                    //paint current region of zoom
                    int offsetSamples = getOffset();
                    double windowSamples = getWindowSamples();
                    int samples = mBigDataArray.length;

                    if (samples > 0) {
                        float x1 = (float) (iW * offsetSamples / samples);
                        float x2 = (float) (iW * (offsetSamples + windowSamples) / samples);

                        canvas.drawRect(iX + x1, iY, iX + x2, iY + iH, mPaintZoomBox);
                    }
                }
            }
        }
        if (mScroller.computeScrollOffset()) {
            setOffset(mScroller.getCurrX(), false);
            refreshGraph();
        }
    }


    void resetArray() {
        Arrays.fill(mValuesArray, 0);
        Arrays.fill(mValuesArray2, 0);
    }

    void refreshView() {
        double maxZoom = getMaxZoomOut();
        setZoom(maxZoom);
        setOffset(0, false);
        computeInset();
        refreshGraph();
    }

    void computeInset() {
        if (mBigDataArray != null) {
            int sampleCount = mBigDataArray.length;
            double pointsPerSample = (double) mInsetSize / sampleCount;

            Arrays.fill(mInsetArray, 0);
            Arrays.fill(mInsetArray2, 0);

            double currentIndex = 0; //points.
            double max = -1.0;
            double min = 1.0;
            double maxAbs = 0.0;
            int index = 0;

            for (int i = 0; i < sampleCount; i++) {
                double value = mBigDataArray[i];
                if (value > max) {
                    max = value;
                }

                if (value < min) {
                    min = value;
                }

                int prevIndexInt = (int) currentIndex;
                currentIndex += pointsPerSample;
                if ((int) currentIndex > prevIndexInt) { //it switched, time to decide
                    mInsetArray[index] = max;
                    mInsetArray2[index] = min;

                    if (Math.abs(max) > maxAbs) maxAbs = Math.abs(max);
                    if (Math.abs(min) > maxAbs) maxAbs = Math.abs(min);

                    max = -1.0;
                    min = 1.0;
                    index++;
                }

                if (index >= mInsetSize)
                    break;
            }

            //now, normalize
            if (maxAbs > 0) {
                for (int i = 0; i < mInsetSize; i++) {
                    mInsetArray[i] /= maxAbs;
                    mInsetArray2[i] /= maxAbs;

                }
            }

        }
    }


    void computeViewArray(double zoomFactorX, int sampleOffset) {
        //zoom factor: how many samples per point. 1.0 = 1.0 samples per point
        // sample offset in samples.
        if (zoomFactorX < 1.0)
            zoomFactorX = 1.0;

        if (mBigDataArray != null) {
            int sampleCount = mBigDataArray.length;
            double samplesPerPoint = zoomFactorX;
            double pointsPerSample = 1.0 / samplesPerPoint;

            resetArray();

            double currentIndex = 0; //points.
            double max = -1.0;
            double min = 1.0;
            int index = 0;

            for (int i = sampleOffset; i < sampleCount; i++) {

                double value = mBigDataArray[i];
                if (value > max) {
                    max = value;
                }

                if (value < min) {
                    min = value;
                }

                int prevIndexInt = (int) currentIndex;
                currentIndex += pointsPerSample;
                if ((int) currentIndex > prevIndexInt) { //it switched, time to decide
                    mValuesArray[index] = max;
                    mValuesArray2[index] = min;

                    max = -1.0;
                    min = 1.0;
                    index++;
                }

                if (index >= mArraySize)
                    break;
            }
        } //big data array not null

        redraw();
    }


    void setData(double[] dataVector, int sampleRate) {
        if (sampleRate < 1)
            throw new IllegalArgumentException("sampleRate must be a positive integer");

        mSamplingRate = sampleRate;
        mBigDataArray = (dataVector != null ? dataVector : mDefaultDataVector);

        if (mHasDimensions) { // only refresh the view if it has been initialized already
            refreshView();
        }
    }

    void redraw() {
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDetector.onTouchEvent(event);
        mSGDetector.onTouchEvent(event);
        //return super.onTouchEvent(event);
        return true;
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = "MyGestureListener";
        private boolean mInDrag = false;

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d(DEBUG_TAG, "onDown: " + event.toString() + " " + TAG);
            if(!mScroller.isFinished()) {
                mScroller.forceFinished(true);
                refreshGraph();
            }
            return true;
        }


        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                               float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: VelocityX: " + velocityX + "  velocityY:  " + velocityY);

            mScroller.fling(mCurrentOffset, 0,
                    (int) (-velocityX * getZoom()),
                    0, 0, mBigDataArray.length, 0, 0);
            refreshGraph();
            return true;
        }


        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            setOffset((int) (distanceX * getZoom()), true);
            refreshGraph();
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

        @Override
        public boolean onDoubleTap(MotionEvent event) {
            Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());

            int tappedSample = (int) (event.getX() * getZoom());
            setZoom(getZoom() / 2);
            setOffset(tappedSample / 2, true);

            refreshGraph();
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Vibrator vibe = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
            if (vibe.hasVibrator()) {
                vibe.vibrate(20);
            }
            setZoom(getMaxZoomOut());
            setOffset(0, false);
            refreshGraph();
        }
    }

    private class MyScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        private static final String DEBUG_TAG = "MyScaleGestureListener";
        int focusSample = 0;


        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            focusSample = (int) (detector.getFocusX() * getZoom()) + mCurrentOffset;
            return super.onScaleBegin(detector);
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            setZoom(getZoom() / detector.getScaleFactor());

            int newFocusSample = (int) (detector.getFocusX() * getZoom()) + mCurrentOffset;
            int sampleDelta = (int) (focusSample - newFocusSample);
            setOffset(sampleDelta, true);
            refreshGraph();
            return true;
        }
    }

    private static void log(String msg) {
        Log.v(TAG, msg);
    }

}
