/*
 * 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 android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewDebug;
import android.widget.FrameLayout;

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

/**
 * Container for two-dimensional chart, drawn with a combination of
 * {@link ChartGridView} and {@link ChartSweepView} children. The entire chart uses
 * {@link ChartAxis} to map between raw values
 * and screen coordinates.
 */
public class ChartView extends FrameLayout {
    // TODO: extend something that supports two-dimensional scrolling

    private static final int SWEEP_GRAVITY = Gravity.TOP | Gravity.START;

    ChartAxis mHoriz;
    ChartAxis mVert;

    @ViewDebug.ExportedProperty
    private int mOptimalWidth = -1;
    private float mOptimalWidthWeight = 0;

    private Rect mContent = new Rect();

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

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

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

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.ChartView, defStyle, 0);
        setOptimalWidth(a.getDimensionPixelSize(R.styleable.ChartView_optimalWidth, -1),
                a.getFloat(R.styleable.ChartView_optimalWidthWeight, 0));
        a.recycle();

        setClipToPadding(false);
        setClipChildren(false);
    }

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

    public void setOptimalWidth(int optimalWidth, float optimalWidthWeight) {
        mOptimalWidth = optimalWidth;
        mOptimalWidthWeight = optimalWidthWeight;
        requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int slack = getMeasuredWidth() - mOptimalWidth;
        if (mOptimalWidth > 0 && slack > 0) {
            final int targetWidth = (int) (mOptimalWidth + (slack * mOptimalWidthWeight));
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mContent.set(getPaddingLeft(), getPaddingTop(), r - l - getPaddingRight(),
                b - t - getPaddingBottom());
        final int width = mContent.width();
        final int height = mContent.height();

        // no scrolling yet, so tell dimensions to fill exactly
        mHoriz.setSize(width);
        mVert.setSize(height);

        final Rect parentRect = new Rect();
        final Rect childRect = new Rect();

        for (int i = 0; i < getChildCount(); i++) {
            final View child = getChildAt(i);
            final LayoutParams params = (LayoutParams) child.getLayoutParams();

            parentRect.set(mContent);

            if (child instanceof ChartGridView) {
                // Grid uses some extra room for labels
                Gravity.apply(params.gravity, width, height, parentRect, childRect);
                child.layout(childRect.left, childRect.top, childRect.right,
                        childRect.bottom + child.getPaddingBottom());

            } else if (child instanceof ChartSweepView) {
                layoutSweep((ChartSweepView) child, parentRect, childRect);
                child.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
            }
        }
    }

    protected void layoutSweep(ChartSweepView sweep) {
        final Rect parentRect = new Rect(mContent);
        final Rect childRect = new Rect();

        layoutSweep(sweep, parentRect, childRect);
        sweep.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
    }

    protected void layoutSweep(ChartSweepView sweep, Rect parentRect, Rect childRect) {
        final Rect sweepMargins = sweep.getMargins();

        // sweep is always placed along specific dimension
        if (sweep.getFollowAxis() == ChartSweepView.VERTICAL) {
            parentRect.top += sweepMargins.top + (int) sweep.getPoint();
            parentRect.bottom = parentRect.top;
            parentRect.left += sweepMargins.left;
            parentRect.right += sweepMargins.right;
            Gravity.apply(SWEEP_GRAVITY, parentRect.width(), sweep.getMeasuredHeight(),
                    parentRect, childRect);

        } else {
            parentRect.left += sweepMargins.left + (int) sweep.getPoint();
            parentRect.right = parentRect.left;
            parentRect.top += sweepMargins.top;
            parentRect.bottom += sweepMargins.bottom;
            Gravity.apply(SWEEP_GRAVITY, sweep.getMeasuredWidth(), parentRect.height(),
                    parentRect, childRect);
        }
    }
}
