/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2009 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people
listed in contributors.txt.

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 2
of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

struct ClcContact {
	BYTE type;
	BYTE flags;
	union {
		struct {
			WORD iImage;
			HANDLE hContact;
		};
		struct {
			WORD groupId;
			struct ClcGroup *group;
		};
	};
	BYTE  iExtraImage[MAXEXTRACOLUMNS];
	TCHAR szText[120-MAXEXTRACOLUMNS];
	char * proto;	// MS_PROTO_GETBASEPROTO
};

struct ClcData {
	struct ClcGroup list;
	int rowHeight;
	int yScroll;
	int selection;
	struct ClcFontInfo fontInfo[FONTID_MAX + 1];
	int scrollTime;
	HIMAGELIST himlHighlight;
	int groupIndent;
	TCHAR szQuickSearch[128];
	int iconXSpace;
	HWND hwndRenameEdit;
	COLORREF bkColour, selBkColour, selTextColour, hotTextColour, quickSearchColour;
	int iDragItem, iInsertionMark;
	int dragStage;
	POINT ptDragStart;
	int dragAutoScrolling;
	int dragAutoScrollHeight;
	int leftMargin;
	int insertionMarkHitHeight;
	HBITMAP hBmpBackground;
	int backgroundBmpUse, bkChanged;
	int iHotTrack;
	int gammaCorrection;
	DWORD greyoutFlags;			  //see m_clc.h
	DWORD offlineModes;
	DWORD exStyle;
	POINT ptInfoTip;
	int infoTipTimeout;
	HANDLE hInfoTipItem;
	HIMAGELIST himlExtraColumns;
	int extraColumnsCount;
	int extraColumnSpacing;
	int checkboxSize;
	int showSelAlways;
	int showIdle;
	int noVScrollbar;
	int useWindowsColours;
	int needsResort;
};

/* clc.c */
extern int g_IconWidth, g_IconHeight;

void   fnClcOptionsChanged(void);
void   fnClcBroadcast(int msg, WPARAM wParam, LPARAM lParam);
HMENU  fnBuildGroupPopupMenu(struct ClcGroup* group);

LRESULT CALLBACK fnContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

/* clcidents.c */
int    fnGetRowsPriorTo(struct ClcGroup *group, struct ClcGroup *subgroup, int contactIndex);
int    fnFindItem(HWND hwnd, struct ClcData *dat, HANDLE hItem, struct ClcContact **contact, struct ClcGroup **subgroup, int *isVisible);
int    fnGetRowByIndex(struct ClcData *dat, int testindex, struct ClcContact **contact, struct ClcGroup **subgroup);
HANDLE fnContactToHItem(struct ClcContact* contact);
HANDLE fnContactToItemHandle(struct ClcContact * contact, DWORD * nmFlags);

/* clcitems.c */
struct ClcGroup* fnAddGroup(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers);
struct ClcGroup* fnRemoveItemFromGroup(HWND hwnd, struct ClcGroup *group, struct ClcContact *contact, int updateTotalCount);

void fnFreeContact(struct ClcContact *p);
void fnFreeGroup(struct ClcGroup *group);
int  fnAddInfoItemToGroup(struct ClcGroup *group, int flags, const TCHAR *pszText);
int  fnAddItemToGroup(struct ClcGroup *group, int iAboveItem);
void fnAddContactToTree(HWND hwnd, struct ClcData *dat, HANDLE hContact, int updateTotalCount, int checkHideOffline);
int  fnAddContactToGroup(struct ClcData *dat, struct ClcGroup *group, HANDLE hContact);
void fnDeleteItemFromTree(HWND hwnd, HANDLE hItem);
void fnRebuildEntireList(HWND hwnd, struct ClcData *dat);
int  fnGetGroupContentsCount(struct ClcGroup *group, int visibleOnly);
void fnSortCLC(HWND hwnd, struct ClcData *dat, int useInsertionSort);
void fnSaveStateAndRebuildList(HWND hwnd, struct ClcData *dat);

/* clcmsgs.c */
LRESULT fnProcessExternalMessages(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam);

/* clcutils.c */
char* fnGetGroupCountsText(struct ClcData *dat, struct ClcContact *contact);
int   fnHitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, struct ClcContact **contact, struct ClcGroup **group, DWORD * flags);
void  fnScrollTo(HWND hwnd, struct ClcData *dat, int desty, int noSmooth);
void  fnEnsureVisible(HWND hwnd, struct ClcData *dat, int iItem, int partialOk);
void  fnRecalcScrollBar(HWND hwnd, struct ClcData *dat);
void  fnSetGroupExpand(HWND hwnd, struct ClcData *dat, struct ClcGroup *group, int newState);
void  fnDoSelectionDefaultAction(HWND hwnd, struct ClcData *dat);
int   fnFindRowByText(HWND hwnd, struct ClcData *dat, const TCHAR *text, int prefixOk);
void  fnEndRename(HWND hwnd, struct ClcData *dat, int save);
void  fnDeleteFromContactList(HWND hwnd, struct ClcData *dat);
void  fnBeginRenameSelection(HWND hwnd, struct ClcData *dat);
void  fnCalcEipPosition(struct ClcData *dat, struct ClcContact *contact, struct ClcGroup *group, POINT *result);
int   fnGetDropTargetInformation(HWND hwnd, struct ClcData *dat, POINT pt);
int   fnClcStatusToPf2(int status);
int   fnIsHiddenMode(struct ClcData *dat, int status);
void  fnHideInfoTip(HWND hwnd, struct ClcData *dat);
void  fnNotifyNewContact(HWND hwnd, HANDLE hContact);
DWORD fnGetDefaultExStyle(void);
void  fnGetSetting(int i, LOGFONT* lf, COLORREF* colour);
void  fnGetDefaultFontSetting(int i, LOGFONT* lf, COLORREF* colour);
void  fnGetFontSetting(int i, LOGFONT* lf, COLORREF* colour);
void  fnLoadClcOptions(HWND hwnd, struct ClcData *dat);
void  fnRecalculateGroupCheckboxes(HWND hwnd, struct ClcData *dat);
void  fnSetGroupChildCheckboxes(struct ClcGroup *group, int checked);
void  fnInvalidateItem(HWND hwnd, struct ClcData *dat, int iItem);

int fnGetRowBottomY(struct ClcData *dat, int item);
int fnGetRowHeight(struct ClcData *dat, int item);
int fnGetRowTopY(struct ClcData *dat, int item);
int fnGetRowTotalHeight(struct ClcData *dat);
int fnRowHitTest(struct ClcData *dat, int y);

/* clcopts.c */
int ClcOptInit(WPARAM wParam, LPARAM lParam);
DWORD GetDefaultExStyle(void);
void GetFontSetting(int i, LOGFONTA *lf, COLORREF *colour);

/* clistmenus.c */
HGENMENU fnGetProtocolMenu(const char*);
int      fnGetProtocolVisibility(const char* accName);
int      fnConvertMenu(CLISTMENUITEM*, TMO_MenuItem*);

int      fnGetAccountIndexByPos(int Pos);
int      fnGetProtoIndexByPos(PROTOCOLDESCRIPTOR ** proto, int protoCnt, int Pos);
void     RebuildMenuOrder(void);

INT_PTR  MenuProcessCommand(WPARAM wParam, LPARAM lParam);

/* clistsettings.c */
TCHAR* fnGetContactDisplayName(HANDLE hContact, int mode);
void   fnGetDefaultFontSetting(int i, LOGFONT* lf, COLORREF * colour);
void   fnInvalidateDisplayNameCacheEntry(HANDLE hContact);

ClcCacheEntryBase* fnGetCacheEntry(HANDLE hContact);
ClcCacheEntryBase* fnCreateCacheItem (HANDLE hContact);
void fnCheckCacheItem(ClcCacheEntryBase* p);
void fnFreeCacheItem(ClcCacheEntryBase* p);

/* clcfiledrop.c */
void InitFileDropping(void);

void   fnRegisterFileDropping (HWND hwnd);
void   fnUnregisterFileDropping (HWND hwnd);

/* clistevents.c */
struct CListEvent* fnAddEvent(CLISTEVENT *cle);
CLISTEVENT* fnGetEvent(HANDLE hContact, int idx);

struct CListEvent* fnCreateEvent(void);
void fnFreeEvent(struct CListEvent* p);

int   fnEventsProcessContactDoubleClick(HANDLE hContact);
int   fnEventsProcessTrayDoubleClick(int);
int   fnGetImlIconIndex(HICON hIcon);
int   fnRemoveEvent(HANDLE hContact, HANDLE dbEvent);

/* clistmod.c */
int    fnIconFromStatusMode(const char *szProto, int status, HANDLE hContact);
int    fnShowHide(WPARAM wParam, LPARAM lParam);
HICON  fnGetIconFromStatusMode(HANDLE hContact, const char *szProto, int status);
TCHAR* fnGetStatusModeDescription(int wParam, int lParam);
int    fnGetWindowVisibleState(HWND hWnd, int iStepX, int iStepY);

/* clisttray.c */
void   fnInitTray(void);
void   fnUninitTray(void);
void   fnLockTray(void);
void   fnUnlockTray(void);
int    fnCListTrayNotify(MIRANDASYSTRAYNOTIFY *msn);
int    fnTrayIconAdd(HWND hwnd, const char *szProto, const char *szIconProto, int status);
int    fnTrayIconDestroy(HWND hwnd);
void   fnTrayIconIconsChanged (void);
int    fnTrayIconInit(HWND hwnd);
TCHAR* fnTrayIconMakeTooltip(const TCHAR *szPrefix, const char *szProto);
int    fnTrayIconPauseAutoHide (WPARAM wParam, LPARAM lParam);
INT_PTR    fnTrayIconProcessMessage (WPARAM wParam, LPARAM lParam);
void   fnTrayIconRemove(HWND hwnd, const char *szProto);
int    fnTrayIconSetBaseInfo(HICON hIcon, const char *szPreferredProto);
void   fnTrayIconSetToBase (char *szPreferredProto);
void   fnTrayIconTaskbarCreated(HWND hwnd);
int    fnTrayIconUpdate(HICON hNewIcon, const TCHAR *szNewTip, const char *szPreferredProto, int isBase);
void   fnTrayIconUpdateBase (const char *szChangedProto);
void   fnTrayIconUpdateWithImageList (int iImage, const TCHAR *szNewTip, char *szPreferredProto);

VOID CALLBACK fnTrayCycleTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime);

/* clui.c */
LRESULT CALLBACK fnContactListWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void fnLoadCluiGlobalOpts(void);
void fnCluiProtocolStatusChanged(int, const char*);
void fnDrawMenuItem(DRAWITEMSTRUCT *dis, HICON hIcon, HICON eventIcon);

/* contact.c */
void fnChangeContactIcon (HANDLE hContact, int iIcon, int add);
void fnLoadContactTree (void);
int  fnCompareContacts (const struct ClcContact *contact1, const struct ClcContact *contact2);
void fnSortContacts (void);
int  fnSetHideOffline (WPARAM wParam, LPARAM lParam);

/* docking.c */
int fnDocking_ProcessWindowMessage (WPARAM wParam, LPARAM lParam);

/* group.c */
TCHAR* fnGetGroupName (int idx, DWORD* pdwFlags);
int    fnRenameGroup (int groupID, TCHAR* newName);

/* keyboard.c */
int  fnHotKeysRegister (HWND hwnd);
void fnHotKeysUnregister (HWND hwnd);
int  fnHotKeysProcess (HWND hwnd, WPARAM wParam, LPARAM lParam);
int  fnHotkeysProcessMessage (WPARAM wParam, LPARAM lParam);