/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
// UISplitterWnd.cpp : インプリメンテーション ファイル

#include "stdafx.h"
#include "UISplitterWnd.h"

#include "fugenView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CUISplitterWnd
IMPLEMENT_DYNAMIC(CUISplitterWnd, CSplitterWnd)

CUISplitterWnd::CUISplitterWnd(){}

CUISplitterWnd::~CUISplitterWnd(){}

// simple "wiper" splitter
BOOL CUISplitterWnd::CreateStaticEx(CWnd* pParentWnd,
	int maxRows, int maxCols, CCreateContext* pContext, DWORD dwStyle, UINT nID)
{
	ASSERT(pParentWnd != NULL);
	ASSERT(pContext != NULL);
	ASSERT(pContext->m_pNewViewClass != NULL);
	ASSERT(maxRows >= 1 && maxRows <= 16);
	ASSERT(maxCols >= 1 && maxCols <= 16);
	ASSERT(maxCols > 1 || maxRows > 1);     // 1x1 is not permitted
	ASSERT(dwStyle & WS_CHILD);
	ASSERT(!(dwStyle & SPLS_DYNAMIC_SPLIT)); // can't have dynamic split

	ASSERT(m_nRows == 0 && m_nCols == 0);       // none yet
	m_nMaxRows = maxRows;
	m_nMaxCols = maxCols;
	m_nRows = 1;
	m_nCols = 1;

	// create with zero minimum pane size
	if (!CreateCommon(pParentWnd, CSize(0, 0), dwStyle, nID))
		return FALSE;

	ASSERT(pContext->m_pNewViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
	m_pDynamicViewClass = pContext->m_pNewViewClass;
		// save for later dynamic creations

	//(0,0)にあたるViewを作っておく
	// add the first initial pane
	if (!CreateView(0, 0,  m_pDynamicViewClass, CSize(0,0), pContext))	{
		DestroyWindow(); // will clean up child windows
		return FALSE;
	}

	// all panes must be created with explicit calls to CreateView
	return TRUE;
}
void CUISplitterWnd::RecalcViewSize()
{
	CRect rectInside;
	GetInsideRect(rectInside);

	// layout columns (restrict to possible sizes)
	int i;
	int colWidth = (rectInside.Width() - (m_cxSplitterGap*(m_nCols-1)))/m_nCols;
	for(i=0;i<m_nCols;i++){
		m_pColInfo[i].nIdealSize = colWidth;
	}
	int rowWidth = (rectInside.Height() - (m_cySplitterGap*(m_nRows-1)))/m_nRows;
	for(i=0;i<m_nRows;i++){
		m_pRowInfo[i].nIdealSize = rowWidth;
	}
}

void CUISplitterWnd::ResetViewNums(int nRow, int nCol){
	ASSERT_VALID(this);
	ASSERT(nRow <= m_nMaxRows);
	ASSERT(nCol <= m_nMaxCols);
	m_nRows=nRow;
	m_nCols=nCol;

}


BEGIN_MESSAGE_MAP(CUISplitterWnd, CSplitterWnd)
	//{{AFX_MSG_MAP(CUISplitterWnd)
	ON_WM_SIZE()
	//ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUISplitterWnd メッセージ ハンドラ
void CUISplitterWnd::OnSize(UINT nType, int cx, int cy) {
	// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
	if (nType != SIZE_MINIMIZED && cx > 0 && cy > 0){
		//リサイズ時のサイズ合わせ。
		if(m_sizePrev.cx >0 && m_sizePrev.cy > 0){
			CSplitterWnd::CRowColInfo* pInfo;
			int i;
			//ColSize
			for(i = 0, pInfo = m_pColInfo; i<m_nMaxCols; i++,pInfo++){
				pInfo->nIdealSize = (int)(pInfo->nIdealSize * cx/m_sizePrev.cx);
			}
			//RowSize
			for(i = 0, pInfo = m_pRowInfo; i<m_nMaxRows; i++,pInfo++){
				pInfo->nIdealSize = (int)(pInfo->nIdealSize * cy/m_sizePrev.cy);
			}

		}
		m_sizePrev.cx = cx;
		m_sizePrev.cy = cy;
	}
	
	CSplitterWnd::OnSize(nType, cx, cy);
}


//! SetActivePane( int row, int col, CWnd* pWnd)
/*!
	オリジナルをそのままCALLしている。
*/
void CUISplitterWnd::SetActivePane( int row, int col, CWnd* pWnd){
	CSplitterWnd::SetActivePane(row, col, pWnd);
}

//! CanActivateNext(BOOL)
/*!
	とりあえずオリジナルをコピペ
	そのままでよさそうだ。
*/
BOOL CUISplitterWnd::CanActivateNext(BOOL){
	ASSERT_VALID(this);

	if (GetActivePane() == NULL){
		TRACE0("Warning: Can't go to next pane - there is no current pane.\n");
		return FALSE;
	}
	ASSERT(m_nRows != 0);
	ASSERT(m_nCols != 0);
	// if more than 1x1 we can go to the next or prev pane
	return (m_nRows > 1) || (m_nCols > 1);
}

//! ActivateNext(BOOL)
/*!
	とりあえずオリジナルをコピペ

  以下の仕様で実装すること。
	最後のPane<->先頭に移動するジャンプする際は
	ジャンプする前に親ウィンドウがCSplitterWndかどうか調べる。
	親がCSplitterWndの場合は親ウィンドウの次/前に移動

	移動先のウインドウがCSplitterWndの場合はSplitterWndの先頭/末尾に
	移動する。

*/
void CUISplitterWnd::ActivateNext(BOOL bPrev){
	ASSERT_VALID(this);

	// find the coordinate of the current pane
	int row, col;
	if (GetActivePane(&row, &col) == NULL){
		TRACE0("Warning: Cannot go to next pane - there is no current view.\n");
		return;
	}
	ASSERT(row >= 0 && row < m_nRows);
	ASSERT(col >= 0 && col < m_nCols);

	// determine next pane
	if (bPrev)	{
		// prev
		if (--col < 0){
			col = m_nCols - 1;
			if (--row < 0)
				row = m_nRows - 1;
		}
	}else{
		// next
		if (++col >= m_nCols){
			col = 0;
			if (++row >= m_nRows)
				row = 0;
		}
	}
	// set newly active pane
//	SetActivePane(row, col);
	SetActivePane(row, col, GetPane(row, col));
}

void CUISplitterWnd::OnInvertTracker(const CRect& rect)
{
	CSplitterWnd::OnInvertTracker(rect);

	// トラッキング中に動きがもっさりするのを解消するには
	// ここから下をコメントアウト。
	// ただし、再描画領域は単純な塗りつぶしになる
	int nrow = GetRowCount();
	int ncol = GetColumnCount();
	for(int row = 0 ; row < nrow ; row++) {
		for(int col = 0 ; col < ncol ; col++) {
			fugenView* view = (fugenView*)GetPane(row, col);
			view->redrawOnlythis();
			//view->Invalidate();
		}
	}
}

void CUISplitterWnd::RecalcLayout()    // call after changing sizes
{
	CSplitterWnd::RecalcLayout();
	
	
	int nrow = GetRowCount();
	int ncol = GetColumnCount();
	for(int row = 0 ; row < nrow ; row++) {
		for(int col = 0 ; col < ncol ; col++) {
			fugenView* view = (fugenView*)GetPane(row, col);
			// redrawOnlythisだと、作成直後の呼び出しでエラーがでるので
			// Invalidate()にする。
			//view->redrawOnlythis();
			view->Invalidate();
		}
	}
}
