#include "TwistPane.h"

const short kTwistPaneIconsID = 8593;

TwistPane::TwistPane()
: mTriangle(kTwistPaneIconsID), mHeader(0L), mOpen(true), mSubpane(0L),
  mNextPane(0L)
{
	// don't let the triangle pop back after being clicked
	mTriangle.mPopBack = false;
	
}

TwistPane::~TwistPane()
{
	// destroy subpanes
	if (mHeader) delete mHeader;
	if (mSubpane) delete mSubpane;
}

void TwistPane::Draw()
{
	DrawHeader(false);
	if (mOpen) DrawSubpane(false);
}

Boolean TwistPane::Click(Point where, short modifiers)
{
	if (mTriangle.Contains(where)) {
		mTriangle.Click(where, modifiers);
		SetOpen (mTriangle.mState > 0);
		return true;
	}
	return false;
}

void TwistPane::DrawTriangle(const Boolean erase)
{
	// adjust and draw the twisty triangle
	OffsetRect( &mTriangle.mFrame, 
		mFrame.left - mTriangle.mFrame.left, mFrame.top - mTriangle.mFrame.top );
	mTriangle.mState = mOpen;
	if (erase) EraseRect( &mTriangle.mFrame );
	mTriangle.Draw();
}

void TwistPane::DrawHeader(const Boolean erase)
{
	// find the header region and erase it, if needed	
	Rect r = mFrame;
	if (mHeader) {
		OffsetRect( &mHeader->mFrame, 
		mFrame.left - mHeader->mFrame.left + 24, mFrame.top - mHeader->mFrame.top );
		r.bottom = mHeader->mFrame.bottom;
	} else {
		r.bottom = r.top + 12;
	}
	
	if (erase) EraseRect( &r );
	DrawTriangle(false);
	if (mHeader) mHeader->Draw();
}

void TwistPane::SetOpen(const Boolean open)
{
	// erase next pane (it'll need to be moved)
	if (mNextPane) {
		EraseRect( &mNextPane->mFrame );		
	}
	
	// adjust and redraw self
	mOpen = open;
	if (mSubpane) mSubpane->mHidden = !mOpen;
	DrawTriangle(true);
	DrawSubpane(true);
	if (mHeader) mFrame.bottom = mHeader->mFrame.bottom;
	else mFrame.bottom = mFrame.top + 12;
	if (mOpen and mSubpane) mFrame.bottom = mSubpane->mFrame.bottom;	
	
	// adjust and redraw the next pane below us (if any)
	if (mNextPane and mNextPane->mFrame.top != mFrame.bottom + 8) {
		OffsetRect( &mNextPane->mFrame, 0, (mFrame.bottom+8 - mNextPane->mFrame.top) );
		mNextPane->Draw();
	}
}

void TwistPane::DrawSubpane(const Boolean erase)
{
	if (!mSubpane) return;

	// adjust position
	OffsetRect( &mSubpane->mFrame, 
			mFrame.left - mSubpane->mFrame.left + 32, 
			mFrame.top - mSubpane->mFrame.top  + 16);
	
	// draw it
	if (erase) EraseRect( &mSubpane->mFrame );
	if (mOpen) mSubpane->Draw();
	
}