/* Anakrino - .NET Reflection Browser
 * Copyright (C) 2001-2002  Jay Freeman (saurik)
*/

/*
 *        Redistribution and use in source and binary
 * forms, with or without modification, are permitted
 * provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer in the documentation
 *    and/or other materials provided with the
 *    distribution.
 * 3. The name of the author may not be used to endorse
 *    or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef ANAKRINO_BROWSERTAB_H
#define ANAKRINO_BROWSERTAB_H

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "anakrino/IBinder.h"
#include "anakrino/IBrowser.h"

#include "MicrosoftTab.h"

namespace Anakrino {

class BrowserTab :
	public CWindowImpl<BrowserTab>
{
  private:
	CStatic m_Static;
	CMicrosoftTabCtrl m_Tabber;

	typedef std::vector< Diapexis::Handle<IBrowser> > BrowserVector;
	BrowserVector m_Browsers;

  public:
	DECLARE_WND_SUPERCLASS(NULL, CWindow::GetWndClassName())

	BEGIN_MSG_MAP(BrowserTab)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		NOTIFY_CODE_HANDLER(TCN_SELCHANGE, OnSelChange)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

	/*virtual BOOL PreTranslateMessage(MSG *pMsg) {
		for (BrowserVector::iterator browser = m_Browsers.begin(); browser != m_Browsers.end(); browser++)
			if ((*browser)->PreTranslateMessage(pMsg))
				return TRUE;
		return FALSE;
	}*/

	void Bind(Metallurgy::Assembly *mAssembly) {
		for (BrowserVector::iterator browser(m_Browsers.begin()); browser != m_Browsers.end(); browser++)
			(*browser)->Bind(mAssembly);
	}

	void Refresh() {
		for (BrowserVector::iterator browser(m_Browsers.begin()); browser != m_Browsers.end(); browser++)
			(*browser)->Refresh();
	}

	void Destroy() {
		for (BrowserVector::iterator browser(m_Browsers.begin()); browser != m_Browsers.end(); browser++)
			(*browser)->Destroy();
	}

	LRESULT OnSelChange(int wParam, LPNMHDR lParam, BOOL &bHandled) {
		Update();
		return 0;
	}

	void Update() {
		RECT rect;
		GetWindowRect(&rect);
		m_Tabber.SetWindowPos(NULL, 0, 0, rect.right - rect.left, 21, SWP_NOZORDER);
		m_Tabber.UpdateLayout();
		m_Tabber.Invalidate();

		for (int i(0); i < m_Browsers.size(); i++) {
			::SetWindowPos(*m_Browsers[i], NULL, 0, 21, rect.right - rect.left, rect.bottom - rect.top - 21, SWP_NOZORDER);
			::ShowWindow(*m_Browsers[i], i == m_Tabber.GetCurSel() ? SW_SHOW : SW_HIDE);
		}
	}

	LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) {
		if (wParam != SIZE_MINIMIZED)
			if (m_Static != NULL)
				Update();
		bHandled = FALSE;
		return 1;
	}

	void Initialize(IBinder *binder, HWND parent, DOM_NodeList nodes) {
		Create(parent, rcDefault, NULL, WS_CHILD | WS_VISIBLE);
		m_Static.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE);
		m_Tabber.SubclassWindow(m_Static);

		TCITEM i_tab;
		i_tab.mask = TCIF_TEXT;

		for (uint32_t i(0); i < nodes.getLength(); i++) {
			DOM_NamedNodeMap n_browser = nodes.item(i).getAttributes();

			i_tab.pszText = const_cast<wstr_t>(n_browser.getNamedItem("name").getNodeValue().rawBuffer());
			m_Tabber.InsertItem(-1, &i_tab);

			Diapexis::Handle<IBrowser> browser(n_browser.getNamedItem("type").getNodeValue().rawBuffer());
			browser->Initialize(binder, m_hWnd);
			m_Browsers.push_back(browser);
		}

		Update();
	}
};

}

#endif//ANAKRINO_BROWSERTAB_H