/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 1, or (at your option)
** any later version.

** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.

** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com>
 */

#if !defined(AFX_WINCVSBROWSER_H__144A4971_CAB4_11D1_BC80_000000000000__INCLUDED_)
#define AFX_WINCVSBROWSER_H__144A4971_CAB4_11D1_BC80_000000000000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// WinCvsBrowser.h : header file
//

#include <afxcview.h>
#include "CPStr.h"

class KiSelectionHandler;

/////////////////////////////////////////////////////////////////////////////
// CWinCvsBrowser view

class CWinCvsBrowser : public CTreeView
{
// associated classes
public:
    // ensures selection notification is properly issued
    class CSelectionChangeNotifier
    {
    // Attributes
    protected:
        bool m_notify;
        // if true, the object will issue proper selection notification when going out of scope

        bool m_wasLocked;
        // tells if the view was already locked at the time of initialization

        CWinCvsBrowser* m_view;
        // the view to change the state

    // Construction
    public:
        // constructor can be configured either to issue notification or discard it
        CSelectionChangeNotifier(CWinCvsBrowser* view, bool notify)
        : m_notify(notify)
        , m_view(view)
        , m_wasLocked(view->m_isSelectionNotificationLocked)
        { 
            if (!m_wasLocked)
            {
                m_view->m_isSelectionChanged = false;
                m_view->m_isSelectionNotificationLocked = true;
            }
        }

        ~CSelectionChangeNotifier()
        {
            m_view->m_isSelectionNotificationLocked = m_wasLocked;
            if (!m_wasLocked)
            {
                if (m_notify)
                {
                    m_view->NotifySelectionChange();
                }
                m_view->m_isSelectionChanged = false;
            }
        }
    };
    friend CSelectionChangeNotifier;

protected:
	CWinCvsBrowser();           // protected constructor used by dynamic creation
	DECLARE_DYNCREATE(CWinCvsBrowser)

// Attributes
protected:

    bool m_isSelectionNotificationLocked;
    // tells if propagating selection changes is currently locked out

    bool m_isSelectionChanged;
    // flag to tell if selection indeed changed since was set to true
    // valid if m_isSelectionNotificationLocked is true

	bool m_isResetViewPending;
	// tells if request to rebuild the view is pending

// Operations
public:

    void NotifySelectionChange();
    // isues notification on selected item change


	void SetNewStyle(long lStyleMask, BOOL bSetBits);
	
	void DeleteAllItems(HTREEITEM root = 0L);
		// used when resetting and take care about our item data
		// if root != 0L : delete all childs of root (except root)
		// if root == 0L : delete all

	void ResetBrowser(const char *path, bool notifyView = false);
		// set the browser root path.

	void RetrievePath(HTREEITEM item, CStr & path);
		// given an item of the tree, guess the full path.

	bool StepToLocation(const char *path, bool notifyView = false);
		// expand and select the path and optionally synchronize the
		// file view.
		// return true if success, false if error

	void ResetView(bool forceReload = false, bool notifyView = false);
		// force reload or check modifications before redrawing
		// and optionally synchronize the file view.

	inline const char *GetRoot(void) const { return m_root; }

	void OnIgnoreChanged();

	bool ProcessSelectionCommand(KiSelectionHandler* handler);
		// processes a handler for selection command 

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CWinCvsBrowser)
	public:
	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
	virtual void OnInitialUpdate();
	protected:
	virtual void OnDraw(CDC* pDC);      // overridden to draw this view
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	//}}AFX_VIRTUAL

// Implementation
protected:
	CStr m_root;
		// current path of the browser
	static CImageList m_Imagelist;
		// several folders aspects

	void StoreExpanded(std::vector<CStr> & allExpanded, HTREEITEM root = 0L);
	bool DisableCommon();

	HTREEITEM GetItemByLocation(const char *path);

	virtual ~CWinCvsBrowser();
	void OnUpdateCmd(CCmdUI* pCmdUI, BOOL needCvsInfos);
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// Generated message map functions
protected:
	//{{AFX_MSG(CWinCvsBrowser)
	afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnUpdateViewAdd(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewUpdate(CCmdUI* pCmdUI);
	afx_msg void OnViewAdd();
	afx_msg void OnViewCommit();
	afx_msg void OnViewUpdate();
	afx_msg void OnViewQueryUpdate();
	afx_msg void OnViewDiff();
	afx_msg void OnViewLog();
	afx_msg void OnViewStatus();
	afx_msg void OnViewUnlock();
	afx_msg void OnViewWatchOn();
	afx_msg void OnViewWatchOff();
	afx_msg void OnViewEdit();
	afx_msg void OnViewUnedit();
	afx_msg void OnViewWatchers();
	afx_msg void OnViewEditors();
	afx_msg void OnViewRelease();
	afx_msg void OnViewTagNew();
	afx_msg void OnViewTagDelete();
	afx_msg void OnViewTagBranch();
	afx_msg void OnViewExplore();
	afx_msg void OnUpdateViewExplore(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewReload(CCmdUI* pCmdUI);
	afx_msg void OnViewReload();
	afx_msg void OnViewCheckout();
	afx_msg void OnUpdateViewCheckout(CCmdUI* pCmdUI);
	afx_msg void OnViewImport();
	afx_msg void OnUpdateViewImport(CCmdUI* pCmdUI);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnDestroy();
	afx_msg void OnViewReservededit();
	afx_msg void OnViewForceedit();
	afx_msg void OnAppCmdline();
	afx_msg void OnAppRtagbranch();
	afx_msg void OnAppRtagcreate();
	afx_msg void OnAppRtagdelete();
	//}}AFX_MSG
	afx_msg void OnUpdateMacro(CCmdUI* pCmdUI);
	afx_msg BOOL OnMacro(UINT nID);
	afx_msg void OnUpdateCustomize(CCmdUI* pCmdUI);
	afx_msg BOOL OnCustomize(UINT nID);
	afx_msg LRESULT OnResetView(WPARAM, LPARAM);

	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WINCVSBROWSER_H__144A4971_CAB4_11D1_BC80_000000000000__INCLUDED_)
