/*
* Copyright 2010 Google Inc.
*
* 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 net.basilwang.ui.widget;
import net.basilwang.R;
import net.basilwang.utils.CurriculumUtils;
import net.basilwang.utils.DimentionUtils;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.TextView;
/**
* Custom layout that contains and organizes a {@link TimeRulerView} and several
* instances of {@link BlockView}. Also positions current "now" divider using
* {@link R.id#blocks_now} view when applicable.
*/
public class BlocksLayout extends ViewGroup {
private int mColumns = 7;
private TimeRulerView mRulerView;
private FrameLayout mBlocksContainerView;
private HorizontalScrollView mHorizontalScrollView;
private View mNowView;
private FrameLayout mWeekDayHeaderFrameLayout;
public BlocksLayout(Context context) {
this(context, null);
Log.v("test", "BlocksLayout Constructure");
}
public BlocksLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
Log.v("test", "BlocksLayout Constructure");
}
public BlocksLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Log.v("test", "BlocksLayout Constructure");
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BlocksLayout, defStyle, 0);
mColumns = a.getInt(R.styleable.TimeRulerView_headerWidth, mColumns);
a.recycle();
}
private void ensureChildren() {
if (mRulerView == null) {
mRulerView = (TimeRulerView) findViewById(R.id.blocks_ruler);
mRulerView.setDrawingCacheEnabled(true);
}
if (mNowView == null) {
mNowView = findViewById(R.id.blocks_now);
mNowView.setDrawingCacheEnabled(true);
}
if (mBlocksContainerView == null) {
mBlocksContainerView = (FrameLayout) findViewById(R.id.blocks_container);
mBlocksContainerView.setDrawingCacheEnabled(true);
}
if (mHorizontalScrollView == null) {
mHorizontalScrollView = (HorizontalScrollView) findViewById(R.id.horizontal_scroll);
mHorizontalScrollView.setDrawingCacheEnabled(true);
}
//2012-12-01 basilwang very bad smell. findViewById from context
if (mWeekDayHeaderFrameLayout == null) {
mWeekDayHeaderFrameLayout = (FrameLayout) ((Activity)this.getContext()).findViewById(R.id.week_day_container);
// mWeekDayHeaderFrameLayout.setDrawingCacheEnabled(true);
}
}
/**
* Remove any {@link BlockView} instances, leaving only
* {@link TimeRulerView} remaining.
*/
public void removeAllBlocks() {
ensureChildren();
mBlocksContainerView.removeAllViews();
addView(mRulerView);
addView(mNowView);
}
public void addBlock(BlockView blockView) {
ensureChildren();
blockView.setDrawingCacheEnabled(true);
mBlocksContainerView.addView(blockView, 0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
ensureChildren();
Log.v("onMeasure", "BlocksLayout onMeasure");
Log.v("onMeasure", "BlocksLayout's width is" + mRulerView.getMeasuredWidth() );
mRulerView.measure(widthMeasureSpec, heightMeasureSpec);
mWeekDayHeaderFrameLayout.measure(widthMeasureSpec, heightMeasureSpec);
// mNowView.measure(widthMeasureSpec, heightMeasureSpec);
Log.v("onMeasure", "BlocksLayout getHeight is "+getHeight());
// mBlocksContainerView.measure(637, 440);
Log.v("onMeasure", "BlocksLayout's width is" + DimentionUtils.getWindowWidth(this.getContext()) );
//Log.v("onMeasure", "BlocksLayout's height is" + mRulerView.getMeasuredTimeRulerViewHeight());
final int height = mRulerView.getMeasuredHeight();
setMeasuredDimension(resolveSize(DimentionUtils.getWindowWidth(this.getContext()), widthMeasureSpec),
resolveSize(height, heightMeasureSpec));
}
@Override
protected void dispatchDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.dispatchDraw(canvas);
Log.v("BlocksLayout", "BlocksLayout onDraw");
final int blockHeight = mRulerView.getBlockHeight();
final int blockWidth=getBlocksWidth();
final Paint dividerPaint = new Paint();
;
dividerPaint.setColor(Color.rgb(217, 217, 217));
dividerPaint.setStyle(Style.FILL);
final int right = getRight();
Log.v("blocks layout right","blocks layout right is: " +right);
final int classIndexCount = CurriculumUtils.getClassIndexCount();
// Walk left side of canvas drawing timestamps
//final int hours = mEndHour - mStartHour;
for (int i = 0; i < classIndexCount; i++) {
final int dividerY = blockHeight * i;
canvas.drawLine(0, dividerY, right, dividerY, dividerPaint);
}
Log.v("header width","header width is: " +mWeekDayHeaderFrameLayout.getWidth());
Log.v("block width","block width is: " +getBlocksWidth());
//mWeekDayHeaderFrameLayout.layout(0, 0, +getBlocksWidth()*mColumns, mRulerView.getWeekDayHeaderHeight());
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
ensureChildren();
Log.v("onLayout", "BlocksLayout onLayout");
final TimeRulerView rulerView = mRulerView;
final int headerWidth = rulerView.getHeaderWidth();
Log.v("onLayout", "rulerView headerWidth is" + headerWidth);
//final int columnWidth = (getWidth() - headerWidth) / mColumns;
final int columnWidth = getBlocksWidth();
Log.v("onLayout", "blockWidth is" + columnWidth);
rulerView.layout(0, 0, mRulerView.getHeaderWidth(), getHeight());
Log.v("onLayout", "BlocksLayout getHeight is "+getHeight());
mHorizontalScrollView.layout(mRulerView.getHeaderWidth(),0, getWidth(), getHeight());
//2012-12-01 basilwang don't know why we need minus mRulerView.getHeaderWidth().
//2012-12-12 basilwang left is 0 and width is columnWidth*mColumns. IMPORTANT!!
mBlocksContainerView.layout(0,0,columnWidth*mColumns, getHeight());
final int count = mBlocksContainerView.getChildCount();
for (int i = 0; i < count; i++) {
final View child = mBlocksContainerView.getChildAt(i);
if (child.getVisibility() == GONE) continue;
if (child instanceof BlockView) {
final BlockView blockView = (BlockView) child;
final int top = rulerView.getTimeVerticalOffset(blockView.getStartTime());
final int bottom = rulerView.getTimeVerticalOffset(blockView.getEndTime());
//2012-12-12 basilwang don't need plus mRulerView.getHeaderWidth()
final int left = (blockView.getColumn() * columnWidth);
final int right = left + columnWidth;
//Log.v("onLayout", "top"+top+"bottom"+bottom+"left"+left+"right"+right);
child.layout(left, top, right, bottom);
}
}
//2012-12-1 basilwang don't forget to add headerWidth and we must layout mWeekDayHeaderFrameLayout and all its children seperately
mWeekDayHeaderFrameLayout.layout(0, 0, +columnWidth*mColumns, rulerView.getWeekDayHeaderHeight());
for (int i = 1; i <= mColumns; i++) {
final View child = mWeekDayHeaderFrameLayout.getChildAt(i);
if (child instanceof TextView) {
final TextView textView = (TextView) child;
final int top = 0;
final int bottom = rulerView.getWeekDayHeaderHeight();
final int left = headerWidth + (i-1) * columnWidth;
final int right = left + columnWidth;
Log.v("onLayout", "top"+top+"bottom"+bottom+"left"+left+"right"+right);
textView.setGravity(Gravity.CENTER);
child.layout(left, top, right, bottom);
}
}
mWeekDayHeaderFrameLayout.requestLayout();
// // Align now view to match current time
// final View nowView = mNowView;
// final long now = System.currentTimeMillis();
//
// final int top = rulerView.getTimeVerticalOffset(now);
// final int bottom = top + nowView.getMeasuredHeight();
// final int left = 0;
// final int right = getWidth();
//
// nowView.layout(left, top, right, bottom);
}
private int getBlocksWidth()
{
int block=(DimentionUtils.getWindowWidth(this.getContext())-mRulerView.getHeaderWidth())/3;
return block;
}
// private int getMeasuredBlocksContainerWidth()
// {
// return getBlocksWidth()*mColumns;
// }
}