/*
 * Copyright (C) 2015 AChep@xda <artemchep@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */
package com.achep.base.ui.widgets;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.achep.headsup.R;
import com.achep.base.Device;

public class DashboardLayout extends ViewGroup {

    private final float mCellGapX;
    private final float mCellGapY;

    private int mNumRows;
    private final int mNumColumns;

    public DashboardLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        final Resources res = context.getResources();
        mCellGapX = res.getDimension(R.dimen.dashboard_cell_gap_x);
        mCellGapY = res.getDimension(R.dimen.dashboard_cell_gap_y);
        mNumColumns = res.getInteger(R.integer.dashboard_num_columns);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int childCount = getChildCount();
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() -
                (mNumColumns - 1) * mCellGapX);
        float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns);

        int cellHeight = 0;
        int cursor = 0;

        for (int i = 0; i < childCount; i++) {
            DashboardTileView v = (DashboardTileView) getChildAt(i);
            if (v.getVisibility() == View.GONE) continue;

            LayoutParams lp = v.getLayoutParams();
            int colSpan = v.getColumnSpan();
            lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGapX);

            // Measure the child
            int newWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
            int newHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
            v.measure(newWidthSpec, newHeightSpec);

            // Save the cell height
            if (cellHeight <= 0) {
                cellHeight = v.getMeasuredHeight();
            }

            lp.height = cellHeight;

            cursor += colSpan;
        }

        mNumRows = (int) Math.ceil((float) cursor / mNumColumns);
        final int newHeight = (int) ((mNumRows * cellHeight) + ((mNumRows - 1) * mCellGapY)) +
                getPaddingTop() + getPaddingBottom();

        setMeasuredDimension(width, newHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int childCount = getChildCount();
        final boolean isLayoutRtl = isLayoutRtl();
        final int width = getWidth();

        int x = getPaddingStartLeft();
        int y = getPaddingTop();
        int cursor = 0;

        for (int i = 0; i < childCount; i++) {
            final DashboardTileView v = (DashboardTileView) getChildAt(i);
            final LayoutParams lp = v.getLayoutParams();
            if (v.getVisibility() == GONE) continue;

            final int col = cursor % mNumColumns;
            final int colSpan = v.getColumnSpan();

            final int childWidth = lp.width;
            final int childHeight = lp.height;

            int row = cursor / mNumColumns;
            v.setDividerVisibility(row != mNumRows - 1);

            // Push the item to the next row if it can't fit on this one
            if ((col + colSpan) > mNumColumns) {
                x = getPaddingStartLeft();
                y += childHeight + mCellGapY;
                row++;
            }

            final int childLeft = (isLayoutRtl) ? width - x - childWidth : x;
            final int childRight = childLeft + childWidth;

            final int childTop = y;
            final int childBottom = childTop + childHeight;

            // Layout the container
            v.layout(childLeft, childTop, childRight, childBottom);

            // Offset the position by the cell gap or reset the position and cursor when we
            // reach the end of the row
            cursor += v.getColumnSpan();
            if (cursor < (((row + 1) * mNumColumns))) {
                x += childWidth + mCellGapX;
            } else {
                x = getPaddingStartLeft();
                y += childHeight + mCellGapY;
            }
        }
    }

    /**
     * @return {@code true} if this layout is Right-to-left, otherwise,
     * or if this device's Android version doesn't support RTL, it
     * returns {@code false}
     */
    @SuppressLint("NewApi")
    private boolean isLayoutRtl() {
        return Device.hasJellyBeanMR1Api() && getLayoutDirection() == LAYOUT_DIRECTION_RTL;
    }

    @SuppressLint("NewApi")
    private int getPaddingStartLeft() {
        return Device.hasJellyBeanMR1Api()
                ? getPaddingStart()
                : getPaddingLeft();
    }

}
