#pragma once
#include "afxwin.h"
#include "LogDlg.h"
#include "BrowseRefsDlg.h"

class CChooseVersion
{
public:
	CString m_initialRefName;
	
private:
	CWnd *	m_pWin;
protected:
	CHistoryCombo m_ChooseVersioinBranch;  
	CHistoryCombo m_ChooseVersioinTags;    
	CHistoryCombo m_ChooseVersioinVersion; 

	//Notification when version changed. Can be implemented in derived classes.
	virtual void OnVersionChanged(){}

	afx_msg void OnBnClickedChooseRadio() 
	{
		this->m_ChooseVersioinTags.EnableWindow(FALSE);													
		this->m_ChooseVersioinBranch.EnableWindow(FALSE);					
		this->m_ChooseVersioinVersion.EnableWindow(FALSE);				
		int radio=m_pWin->GetCheckedRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION);
		switch (radio)											
		{															
		case IDC_RADIO_HEAD:										
			break;													
		case IDC_RADIO_BRANCH:										
			this->m_ChooseVersioinBranch.EnableWindow(TRUE);						
			break;													
		case IDC_RADIO_TAGS:										
			this->m_ChooseVersioinTags.EnableWindow(TRUE);						
			break;													
		case IDC_RADIO_VERSION:										
			this->m_ChooseVersioinVersion.EnableWindow(TRUE);						
		break;		
		}
		// enable version browse button if Version is selected
		m_pWin->GetDlgItem(IDC_BUTTON_SHOW)->EnableWindow(radio == IDC_RADIO_VERSION);
		OnVersionChanged();
	}

	void OnBnClickedChooseVersion()
	{
		// use the git log to allow selection of a version
		CLogDlg dlg;
		// tell the dialog to use mode for selecting revisions
		dlg.SetSelect(true);
		// only one revision must be selected however
		dlg.SingleSelection(true);
		if ( dlg.DoModal() == IDOK )
		{
			// get selected hash if any
			CString selectedHash = dlg.GetSelectedHash();
			// load into window, do this even if empty so that it is clear that nothing has been selected
			m_ChooseVersioinVersion.SetWindowText( selectedHash );
			OnVersionChanged();
		}
	}

	void UpdateRevsionName()
	{																			
		int radio=m_pWin->GetCheckedRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION);		
		switch (radio)															
		{																		
		case IDC_RADIO_HEAD:													
			this->m_VersionName=_T("HEAD");											
			break;																
		case IDC_RADIO_BRANCH:													
			this->m_VersionName=m_ChooseVersioinBranch.GetString();									
			break;																
		case IDC_RADIO_TAGS:													
			this->m_VersionName=m_ChooseVersioinTags.GetString();									
			break;																
		case IDC_RADIO_VERSION:													
			this->m_VersionName=m_ChooseVersioinVersion.GetString();									
			break;	
		}
	}			
	void SetDefaultChoose(int id)
	{
		m_pWin->CheckRadioButton(IDC_RADIO_HEAD,IDC_RADIO_VERSION,id);
		OnBnClickedChooseRadio();
	}

	void OnBnClickedButtonBrowseRef()
	{
		CString origRef;
		UpdateRevsionName();
		CString resultRef = CBrowseRefsDlg::PickRef(false, m_VersionName, gPickRef_All);
		if(resultRef.IsEmpty())
			return;
		SelectRef(resultRef, false);
	}

	void SelectRef(CString refName, bool bRefNameIsPossiblyNotFullName = true)
	{
		if(bRefNameIsPossiblyNotFullName)
		{
			//Make sure refName is a full ref name first
			CString fullRefName = g_Git.GetFullRefName(refName);
			if(!fullRefName.IsEmpty())
				refName = fullRefName;
		}

		if(wcsncmp(refName,L"refs/",5)==0)
			refName = refName.Mid(5);
		if(wcsncmp(refName,L"heads/",6)==0)
		{
			refName = refName.Mid(6);
			SetDefaultChoose(IDC_RADIO_BRANCH);
			m_ChooseVersioinBranch.SetCurSel(
				m_ChooseVersioinBranch.FindStringExact(-1, refName));
		}
		else if(wcsncmp(refName,L"remotes/",8)==0)
		{
			SetDefaultChoose(IDC_RADIO_BRANCH);
			m_ChooseVersioinBranch.SetCurSel(
				m_ChooseVersioinBranch.FindStringExact(-1, refName));
		}
		else if(wcsncmp(refName,L"tags/",5)==0)
		{
			refName = refName.Mid(5);
			SetDefaultChoose(IDC_RADIO_TAGS);
			m_ChooseVersioinTags.SetCurSel(
				m_ChooseVersioinTags.FindStringExact(-1, refName));
		}
		OnVersionChanged();
	}


	void Init()
	{	
		m_ChooseVersioinBranch.SetMaxHistoryItems(0x7FFFFFFF);
		m_ChooseVersioinTags.SetMaxHistoryItems(0x7FFFFFFF);

		STRING_VECTOR list;
		g_Git.GetTagList(list);
		m_ChooseVersioinTags.AddString(list);

		list.clear();
		int current;
		g_Git.GetBranchList(list,&current,CGit::BRANCH_ALL);
		m_ChooseVersioinBranch.AddString(list);
		m_ChooseVersioinBranch.SetCurSel(current);


		if(m_initialRefName.IsEmpty())
			OnVersionChanged();
		else
			SelectRef(m_initialRefName);
	}
public:					
	CString m_VersionName;
	CChooseVersion(CWnd *win)
	{
		m_pWin=win;
	};

};


#define CHOOSE_VERSION_DDX \
	DDX_Control(pDX, IDC_COMBOBOXEX_BRANCH,		m_ChooseVersioinBranch); \
	DDX_Control(pDX, IDC_COMBOBOXEX_TAGS,		m_ChooseVersioinTags);     \
	DDX_Control(pDX, IDC_COMBOBOXEX_VERSION,	m_ChooseVersioinVersion);

#define CHOOSE_VERSION_EVENT\
	ON_BN_CLICKED(IDC_RADIO_HEAD,		OnBnClickedChooseRadioHost)\
	ON_BN_CLICKED(IDC_RADIO_BRANCH,		OnBnClickedChooseRadioHost)\
	ON_BN_CLICKED(IDC_RADIO_TAGS,		OnBnClickedChooseRadioHost)\
	ON_BN_CLICKED(IDC_BUTTON_SHOW, 		OnBnClickedShow)\
	ON_BN_CLICKED(IDC_RADIO_VERSION,	OnBnClickedChooseRadioHost)\
	ON_BN_CLICKED(IDC_BUTTON_BROWSE_REF,	OnBnClickedButtonBrowseRefHost)

#define CHOOSE_VERSION_ADDANCHOR								\
	{															\
		AddAnchor(IDC_COMBOBOXEX_BRANCH, TOP_LEFT, TOP_RIGHT);	\
		AddAnchor(IDC_COMBOBOXEX_TAGS, TOP_LEFT, TOP_RIGHT);	\
		AddAnchor(IDC_COMBOBOXEX_VERSION, TOP_LEFT, TOP_RIGHT);	\
		AddAnchor(IDC_GROUP_BASEON, TOP_LEFT, TOP_RIGHT);		\
		AddAnchor(IDC_BUTTON_SHOW,TOP_RIGHT);		\
		AddAnchor(IDC_BUTTON_BROWSE_REF,TOP_RIGHT);		\
	}	

#define CHOOSE_EVENT_RADIO() \
	afx_msg void OnBnClickedChooseRadioHost(){OnBnClickedChooseRadio();}\
	afx_msg void OnBnClickedShow(){OnBnClickedChooseVersion();}\
	afx_msg void OnBnClickedButtonBrowseRefHost(){OnBnClickedButtonBrowseRef();}
