/*
* TV-Browser for Android
* Copyright (C) 2013 René Mach (rene@tvbrowser.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to use, copy, modify or merge the Software,
* furthermore to publish and distribute the Software free of charge without modifications and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.tvbrowser.view;
import java.util.ArrayList;
import java.util.Calendar;
import android.content.Context;
import android.graphics.Canvas;
import org.tvbrowser.tvbrowser.R;
public class TimeBlockProgramTableLayout extends ProgramTableLayout {
//private ArrayList<Integer> mChannelIDsOrdered;
private int[] mBlockHeights;
private int[] mBlockCumulatedHeights;
private int mBlockSize;
private Calendar mCurrentShownDay;
private boolean mGrowToBlock;
public TimeBlockProgramTableLayout(Context context, final ArrayList<Integer> channelIDsOrdered, int blockSize, final Calendar day, boolean growToBlock) {
super(context, channelIDsOrdered);
//mChannelIDsOrdered = channelIDsOrdered;
mGrowToBlock = growToBlock;
mBlockHeights = new int[(ProgramTableLayoutConstants.HOURS/blockSize) + (ProgramTableLayoutConstants.HOURS % blockSize > 0 ? 1 : 0)];
mBlockCumulatedHeights = new int[mBlockHeights.length];
mBlockSize = blockSize;
mCurrentShownDay = day;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int[][] blockHeightCalc = new int[mBlockHeights.length][getColumnCount()];
int[][] blockProgCount = new int[mBlockHeights.length][getColumnCount()];
int widthSpec = MeasureSpec.makeMeasureSpec(ProgramTableLayoutConstants.COLUMN_WIDTH, MeasureSpec.EXACTLY);
for(int i = 0; i < getChildCount(); i++) {
ProgramPanel progPanel = (ProgramPanel)getChildAt(i);
int sortIndex = getIndexForChannelID(progPanel.getChannelID());
int block = progPanel.getStartHour(mCurrentShownDay) / mBlockSize;
if(block >= 0 && sortIndex >= 0 && block < blockProgCount.length) {
progPanel.measure(widthSpec, heightMeasureSpec);
blockHeightCalc[block][sortIndex] += progPanel.getMeasuredHeight();
blockProgCount[block][sortIndex]++;
}
}
int height = 0;
for(int block = 0; block < blockHeightCalc.length; block++) {
int maxBlockHeight = 0;
for(int column : blockHeightCalc[block]) {
maxBlockHeight = Math.max(column, maxBlockHeight);
}
height += maxBlockHeight;
mBlockHeights[block] = maxBlockHeight;
if(block < blockHeightCalc.length) {
mBlockCumulatedHeights[block] = height;
}
}
if(mGrowToBlock) {
int[][] blockCurrentProgCount = new int[mBlockHeights.length][getColumnCount()];
for(int i = 0; i < getChildCount(); i++) {
ProgramPanel progPanel = (ProgramPanel)getChildAt(i);
int sortIndex = getIndexForChannelID(progPanel.getChannelID());
int block = progPanel.getStartHour(mCurrentShownDay) / mBlockSize;
if(block >= 0 && sortIndex >= 0 && block < mBlockHeights.length) {
int maxBlockHeight = mBlockHeights[block];
int heightDiff = maxBlockHeight - blockHeightCalc[block][sortIndex];
int blockProgCountValue = blockProgCount[block][sortIndex];
blockCurrentProgCount[block][sortIndex]++;
int addHeight = heightDiff/blockProgCountValue;
int count = 1;
int endBlock = progPanel.getEndHour(mCurrentShownDay) / mBlockSize;
if(blockCurrentProgCount[block][sortIndex] == blockProgCountValue) {
while((block + count) < (mBlockHeights.length) && blockProgCount[block + count][sortIndex] == 0 && endBlock > block + count) {
addHeight += mBlockHeights[block + count++];
}
if(count == 1) {
addHeight += heightDiff%blockProgCountValue;
}
}
int newHeightSpec = MeasureSpec.makeMeasureSpec(progPanel.getMeasuredHeight() + addHeight, MeasureSpec.EXACTLY);
progPanel.measure(widthSpec, newHeightSpec);
}
}
}
setMeasuredDimension(ProgramTableLayoutConstants.ROW_HEADER + ProgramTableLayoutConstants.GAP + (ProgramTableLayoutConstants.COLUMN_WIDTH+ProgramTableLayoutConstants.GAP) * getColumnCount(), height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int[][] currentBlockHeight = new int[mBlockHeights.length][getColumnCount()];
for(int i = 0; i < getChildCount(); i++) {
ProgramPanel progPanel = (ProgramPanel)getChildAt(i);
int sortIndex = getIndexForChannelID(progPanel.getChannelID());
int block = progPanel.getStartHour(mCurrentShownDay) / mBlockSize;
if(block >= 0 && sortIndex >= 0 && block < currentBlockHeight.length) {
int x = l + ProgramTableLayoutConstants.ROW_HEADER + ProgramTableLayoutConstants.GAP + sortIndex * (ProgramTableLayoutConstants.COLUMN_WIDTH + ProgramTableLayoutConstants.GAP);
int y = t + currentBlockHeight[block][sortIndex];
if(block > 0) {
y += mBlockCumulatedHeights[block-1];
}
currentBlockHeight[block][sortIndex] += progPanel.getMeasuredHeight();
if(progPanel.getVisibility() != GONE) {
progPanel.layout(x, y, x + ProgramTableLayoutConstants.COLUMN_WIDTH + ProgramTableLayoutConstants.GAP, y + progPanel.getMeasuredHeight());
}
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
for(int i = 0; i < mBlockHeights.length; i++) {
if(i % 2 == 1) {
canvas.drawRect(0, mBlockCumulatedHeights[i-1], canvas.getWidth(), mBlockCumulatedHeights[i-1] + mBlockHeights[i], ProgramTableLayoutConstants.BLOCK_PAINT);
}
int y = ProgramTableLayoutConstants.FONT_SIZE_ASCENT;
if(i > 0) {
y += mBlockCumulatedHeights[i-1];
}
int time = i * mBlockSize;
if(time >= 24) {
time -= 24;
}
final String value = getContext().getString(R.string.time_block_time_format, time);
float length = ProgramTableLayoutConstants.TIME_BLOCK_TIME_PAINT.measureText(value);
canvas.drawText(value, ProgramTableLayoutConstants.ROW_HEADER / 2 - length/2, y, ProgramTableLayoutConstants.TIME_BLOCK_TIME_PAINT);
}
for(int i = 0; i < getColumnCount(); i++) {
int x = ProgramTableLayoutConstants.ROW_HEADER + i * (ProgramTableLayoutConstants.COLUMN_WIDTH + ProgramTableLayoutConstants.GAP);
canvas.drawLine(x, 0, x, canvas.getHeight(), ProgramTableLayoutConstants.LINE_PAINT);
}
super.dispatchDraw(canvas);
}
}