/*
 * 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.android.settings.widget;

import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.RectF;
import android.net.NetworkStatsHistory;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.android.internal.util.Preconditions;
import com.android.settings.R;

/**
 * {@link NetworkStatsHistory} series to render inside a {@link ChartView},
 * using {@link ChartAxis} to map into screen coordinates.
 */
public class ChartNetworkSeriesView extends View {
    private static final String TAG = "ChartNetworkSeriesView";
    private static final boolean LOGD = false;

    private static final boolean ESTIMATE_ENABLED = false;

    private ChartAxis mHoriz;
    private ChartAxis mVert;

    private Paint mPaintStroke;
    private Paint mPaintFill;
    private Paint mPaintFillSecondary;
    private Paint mPaintEstimate;

    private NetworkStatsHistory mStats;

    private Path mPathStroke;
    private Path mPathFill;
    private Path mPathEstimate;

    private long mStart;
    private long mEnd;

    private long mPrimaryLeft;
    private long mPrimaryRight;

    /** Series will be extended to reach this end time. */
    private long mEndTime = Long.MIN_VALUE;

    private boolean mPathValid = false;
    private boolean mEstimateVisible = false;

    private long mMax;
    private long mMaxEstimate;

    public ChartNetworkSeriesView(Context context) {
        this(context, null, 0);
    }

    public ChartNetworkSeriesView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ChartNetworkSeriesView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.ChartNetworkSeriesView, defStyle, 0);

        final int stroke = a.getColor(R.styleable.ChartNetworkSeriesView_strokeColor, Color.RED);
        final int fill = a.getColor(R.styleable.ChartNetworkSeriesView_fillColor, Color.RED);
        final int fillSecondary = a.getColor(
                R.styleable.ChartNetworkSeriesView_fillColorSecondary, Color.RED);

        setChartColor(stroke, fill, fillSecondary);
        setWillNotDraw(false);

        a.recycle();

        mPathStroke = new Path();
        mPathFill = new Path();
        mPathEstimate = new Path();
    }

    void init(ChartAxis horiz, ChartAxis vert) {
        mHoriz = Preconditions.checkNotNull(horiz, "missing horiz");
        mVert = Preconditions.checkNotNull(vert, "missing vert");
    }

    public void setChartColor(int stroke, int fill, int fillSecondary) {
        mPaintStroke = new Paint();
        mPaintStroke.setStrokeWidth(4.0f * getResources().getDisplayMetrics().density);
        mPaintStroke.setColor(stroke);
        mPaintStroke.setStyle(Style.STROKE);
        mPaintStroke.setAntiAlias(true);

        mPaintFill = new Paint();
        mPaintFill.setColor(fill);
        mPaintFill.setStyle(Style.FILL);
        mPaintFill.setAntiAlias(true);

        mPaintFillSecondary = new Paint();
        mPaintFillSecondary.setColor(fillSecondary);
        mPaintFillSecondary.setStyle(Style.FILL);
        mPaintFillSecondary.setAntiAlias(true);

        mPaintEstimate = new Paint();
        mPaintEstimate.setStrokeWidth(3.0f);
        mPaintEstimate.setColor(fillSecondary);
        mPaintEstimate.setStyle(Style.STROKE);
        mPaintEstimate.setAntiAlias(true);
        mPaintEstimate.setPathEffect(new DashPathEffect(new float[] { 10, 10 }, 1));
    }

    public void bindNetworkStats(NetworkStatsHistory stats) {
        mStats = stats;
        invalidatePath();
        invalidate();
    }

    public void setBounds(long start, long end) {
        mStart = start;
        mEnd = end;
    }

    /**
     * Set the range to paint with {@link #mPaintFill}, leaving the remaining
     * area to be painted with {@link #mPaintFillSecondary}.
     */
    public void setPrimaryRange(long left, long right) {
        mPrimaryLeft = left;
        mPrimaryRight = right;
        invalidate();
    }

    public void invalidatePath() {
        mPathValid = false;
        mMax = 0;
        invalidate();
    }

    /**
     * Erase any existing {@link Path} and generate series outline based on
     * currently bound {@link NetworkStatsHistory} data.
     */
    private void generatePath() {
        if (LOGD) Log.d(TAG, "generatePath()");

        mMax = 0;
        mPathStroke.reset();
        mPathFill.reset();
        mPathEstimate.reset();
        mPathValid = true;

        // bail when not enough stats to render
        if (mStats == null || mStats.size() < 2) {
            return;
        }

        final int width = getWidth();
        final int height = getHeight();

        boolean started = false;
        float lastX = 0;
        float lastY = height;
        long lastTime = mHoriz.convertToValue(lastX);

        // move into starting position
        mPathStroke.moveTo(lastX, lastY);
        mPathFill.moveTo(lastX, lastY);

        // TODO: count fractional data from first bucket crossing start;
        // currently it only accepts first full bucket.

        long totalData = 0;

        NetworkStatsHistory.Entry entry = null;

        final int start = mStats.getIndexBefore(mStart);
        final int end = mStats.getIndexAfter(mEnd);
        for (int i = start; i <= end; i++) {
            entry = mStats.getValues(i, entry);

            final long startTime = entry.bucketStart;
            final long endTime = startTime + entry.bucketDuration;

            final float startX = mHoriz.convertToPoint(startTime);
            final float endX = mHoriz.convertToPoint(endTime);

            // skip until we find first stats on screen
            if (endX < 0) continue;

            // increment by current bucket total
            totalData += entry.rxBytes + entry.txBytes;

            final float startY = lastY;
            final float endY = mVert.convertToPoint(totalData);

            if (lastTime != startTime) {
                // gap in buckets; line to start of current bucket
                mPathStroke.lineTo(startX, startY);
                mPathFill.lineTo(startX, startY);
            }

            // always draw to end of current bucket
            mPathStroke.lineTo(endX, endY);
            mPathFill.lineTo(endX, endY);

            lastX = endX;
            lastY = endY;
            lastTime = endTime;
        }

        // when data falls short, extend to requested end time
        if (lastTime < mEndTime) {
            lastX = mHoriz.convertToPoint(mEndTime);

            mPathStroke.lineTo(lastX, lastY);
            mPathFill.lineTo(lastX, lastY);
        }

        if (LOGD) {
            final RectF bounds = new RectF();
            mPathFill.computeBounds(bounds, true);
            Log.d(TAG, "onLayout() rendered with bounds=" + bounds.toString() + " and totalData="
                    + totalData);
        }

        // drop to bottom of graph from current location
        mPathFill.lineTo(lastX, height);
        mPathFill.lineTo(0, height);

        mMax = totalData;

        if (ESTIMATE_ENABLED) {
            // build estimated data
            mPathEstimate.moveTo(lastX, lastY);

            final long now = System.currentTimeMillis();
            final long bucketDuration = mStats.getBucketDuration();

            // long window is average over two weeks
            entry = mStats.getValues(lastTime - WEEK_IN_MILLIS * 2, lastTime, now, entry);
            final long longWindow = (entry.rxBytes + entry.txBytes) * bucketDuration
                    / entry.bucketDuration;

            long futureTime = 0;
            while (lastX < width) {
                futureTime += bucketDuration;

                // short window is day average last week
                final long lastWeekTime = lastTime - WEEK_IN_MILLIS + (futureTime % WEEK_IN_MILLIS);
                entry = mStats.getValues(lastWeekTime - DAY_IN_MILLIS, lastWeekTime, now, entry);
                final long shortWindow = (entry.rxBytes + entry.txBytes) * bucketDuration
                        / entry.bucketDuration;

                totalData += (longWindow * 7 + shortWindow * 3) / 10;

                lastX = mHoriz.convertToPoint(lastTime + futureTime);
                lastY = mVert.convertToPoint(totalData);

                mPathEstimate.lineTo(lastX, lastY);
            }

            mMaxEstimate = totalData;
        }

        invalidate();
    }

    public void setEndTime(long endTime) {
        mEndTime = endTime;
    }

    public void setEstimateVisible(boolean estimateVisible) {
        mEstimateVisible = ESTIMATE_ENABLED ? estimateVisible : false;
        invalidate();
    }

    public long getMaxEstimate() {
        return mMaxEstimate;
    }

    public long getMaxVisible() {
        final long maxVisible = mEstimateVisible ? mMaxEstimate : mMax;
        if (maxVisible <= 0 && mStats != null) {
            // haven't generated path yet; fall back to raw data
            final NetworkStatsHistory.Entry entry = mStats.getValues(mStart, mEnd, null);
            return entry.rxBytes + entry.txBytes;
        } else {
            return maxVisible;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int save;

        if (!mPathValid) {
            generatePath();
        }

        final float primaryLeftPoint = mHoriz.convertToPoint(mPrimaryLeft);
        final float primaryRightPoint = mHoriz.convertToPoint(mPrimaryRight);

        if (mEstimateVisible) {
            save = canvas.save();
            canvas.clipRect(0, 0, getWidth(), getHeight());
            canvas.drawPath(mPathEstimate, mPaintEstimate);
            canvas.restoreToCount(save);
        }

        save = canvas.save();
        canvas.clipRect(0, 0, primaryLeftPoint, getHeight());
        canvas.drawPath(mPathFill, mPaintFillSecondary);
        canvas.restoreToCount(save);

        save = canvas.save();
        canvas.clipRect(primaryRightPoint, 0, getWidth(), getHeight());
        canvas.drawPath(mPathFill, mPaintFillSecondary);
        canvas.restoreToCount(save);

        save = canvas.save();
        canvas.clipRect(primaryLeftPoint, 0, primaryRightPoint, getHeight());
        canvas.drawPath(mPathFill, mPaintFill);
        canvas.drawPath(mPathStroke, mPaintStroke);
        canvas.restoreToCount(save);

    }
}
