/** 
 * @file llpanelgroup.h
 *
 * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
 * $License$
 */

#ifndef LL_LLPANELGROUP_H
#define LL_LLPANELGROUP_H

#include "llgroupmgr.h"
#include "llpanel.h"
#include "lltimer.h"

struct LLOfferInfo;

const S32 UPDATE_MEMBERS_PER_FRAME = 500;

// Forward declares
class LLPanelGroupTab;
class LLTabContainerCommon;
class LLAgent;

class LLPanelGroupTabObserver
{
public:
	LLPanelGroupTabObserver() {};
	virtual ~LLPanelGroupTabObserver(){};
	virtual void tabChanged() = 0;
};

class LLPanelGroup : public LLPanel,
					 public LLGroupMgrObserver, 
					 public LLPanelGroupTabObserver
{
public:
	LLPanelGroup(const std::string& filename,
				 const std::string& name,
				 const LLUUID& group_id,
				 const std::string& initial_tab_selected = "");
	virtual ~LLPanelGroup();

	virtual BOOL postBuild();

	static void onBtnOK(void*);
	static void onBtnCancel(void*);
	static void onBtnApply(void*);
	static void onBtnRefresh(void*);
	static void onClickTab(void*,bool);
	void handleClickTab();

	void setGroupID(const LLUUID& group_id);
	void selectTab(std::string tab_name);

	// Called when embedded in a floater during a close attempt.
	BOOL canClose();
	
	// Checks if the current tab needs to be applied, and tries to switch to the requested tab.
	BOOL attemptTransition();
	
	// Switches to the requested tab (will close() if requested is NULL)
	void transitionToTab();

	void updateTabVisibility();

	// Used by attemptTransition to query the user's response to a tab that needs to apply. 
	static void onNotifyCallback(S32 option, void* user_data);
	void handleNotifyCallback(S32 option);

	bool apply();
	void refreshData();
	void close();
	void draw();

	// Group manager observer trigger.
	virtual void changed(LLGroupChange gc);

	// PanelGroupTab observer trigger
	virtual void tabChanged();

	void setAllowEdit(BOOL v) { mAllowEdit = v; }

	void showNotice(const char* subject,
							const char* message,
							const bool& has_inventory,
							const char* inventory_name,
							LLOfferInfo* inventory_offer);
protected:
	LLPanelGroupTab*		mCurrentTab;
	LLPanelGroupTab*		mRequestedTab;
	LLTabContainerCommon*	mTabContainer;
	BOOL mIgnoreTransition;

	LLButton* mApplyBtn;

	LLTimer mRefreshTimer;

	BOOL mForceClose;

	std::string mInitialTab;
	std::string mFilename;

	LLString mDefaultNeedsApplyMesg;
	LLString mWantApplyMesg;

	BOOL mAllowEdit;
	BOOL mShowingNotifyDialog;
};

class LLPanelGroupTab : public LLPanel
{
public:
	LLPanelGroupTab(const std::string& name, const LLUUID& group_id)
	: LLPanel(name), mGroupID(group_id), mAllowEdit(TRUE), mHasModal(FALSE) { }
	virtual ~LLPanelGroupTab();

	// Factory that returns a new LLPanelGroupFoo tab.
	static void* createTab(void* data);

	// Triggered when the tab becomes active.
	virtual void activate() { }
	
	// Triggered when the tab becomes inactive.
	virtual void deactivate() { }

	// Asks if something needs to be applied.
	// If returning true, this function should modify the message to the user.
	virtual bool needsApply(LLString& mesg) { return false; }

	// Asks if there is currently a modal dialog being shown.
	virtual BOOL hasModal() { return mHasModal; }

	// Request to apply current data.
	// If returning fail, this function should modify the message to the user.
	virtual bool apply(LLString& mesg) { return true; }

	// Request a cancel of changes
	virtual void cancel() { }

	// Triggered when group information changes in the group manager.
	virtual void update(LLGroupChange gc) { }

	// This is the text to be displayed when a help button is pressed.
	virtual LLString getHelpText() const { return mHelpText; }

	// Display anything returned by getHelpText
	static void onClickHelp(void* data);
	void handleClickHelp();

	// This just connects the help button callback.
	virtual BOOL postBuild();

	virtual BOOL isVisibleByAgent(LLAgent* agentp);

	void setAllowEdit(BOOL v) { mAllowEdit = v; }

	void addObserver(LLPanelGroupTabObserver *obs);
	void removeObserver(LLPanelGroupTabObserver *obs);
	void notifyObservers();

protected:
	LLUUID	mGroupID;
	LLTabContainerCommon*	mTabContainer;
	LLString	mHelpText;

	BOOL mAllowEdit;
	BOOL mHasModal;

	typedef std::set<LLPanelGroupTabObserver*> observer_list_t;
	observer_list_t mObservers;
};

#endif // LL_LLPANELGROUP_H
