/* Anakrino - .NET Reflection Viewer
 * 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_VIEWERTAB_H
#define ANAKRINO_VIEWERTAB_H

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "anakrino/IBinder.h"
#include "anakrino/IViewer.h"

#include "MicrosoftTab.h"

namespace Anakrino {

class ViewerTab :
	public CWindowImpl<ViewerTab>
{
  private:
	CStatic m_Static;
	CMicrosoftTabCtrl m_Tabber;

	IBinder *binder;

	typedef std::vector< Diapexis::Handle<IViewer> > ViewerVector;
	ViewerVector m_Viewers;

  public:
	BEGIN_MSG_MAP(ViewerTab)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		NOTIFY_CODE_HANDLER(TCN_SELCHANGE, OnSelChange)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

	/*virtual BOOL PreTranslateMessage(MSG *pMsg) {
		for (ViewerVector::iterator viewer = m_Viewers.begin(); viewer != m_Viewers.end(); viewer++)
			if ((*viewer)->PreTranslateMessage(pMsg))
				return TRUE;
		return FALSE;
	}*/

	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();

		uint32_t current;

		if (m_Tabber.GetCurSel() == -1)
			current = -1;
		else {
			TCITEM item;
			item.mask = TCIF_PARAM;

			m_Tabber.GetItem(m_Tabber.GetCurSel(), &item);
			current = item.lParam;
		}

		for (int i(0); i < m_Viewers.size(); i++) {
			::SetWindowPos(*m_Viewers[i], NULL, 0, 21, rect.right - rect.left, rect.bottom - rect.top - 21, SWP_NOZORDER);
			::ShowWindow(*m_Viewers[i], i == current ? 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 Update(const Metallurgy::Token *token) {
		TCITEM item;
		item.mask = TCIF_TEXT | TCIF_PARAM;

		m_Tabber.DeleteAllItems();
		//uint32_t current(-1);

		for (uint32_t i(0), count(0); i < m_Viewers.size(); i++)
			if (m_Viewers[i]->Supports(token)) {
				/*if (current == -1)
					current = count;*/
				item.pszText = const_cast<wstr_t>(m_Viewers[i]->GetName());
				item.lParam = i;
				m_Tabber.InsertItem(i, &item);
				m_Viewers[i]->Select(token);
			}

		m_Tabber.SetCurSel(0);
		Update();

		/*if (m_CurrentViewer != -1) {
			SetViewer(m_Viewers[m_CurrentViewer]);
			m_Viewers[m_CurrentViewer]->Select(token);
		}*/
	}

	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);

		for (uint32_t i(0); i < nodes.getLength(); i++) {
			DOM_NamedNodeMap n_viewer = nodes.item(i).getAttributes();

			Diapexis::Handle<IViewer> viewer(n_viewer.getNamedItem("type").getNodeValue().rawBuffer());
			viewer->Initialize(binder, m_hWnd);
			m_Viewers.push_back(viewer);
		}
	}
};

}

#endif//ANAKRINO_VIEWERTAB_H