/***************************************************************************
 *   Copyright (C) 2008 by SK Communications.                              *
 *   http://kldp.net/projects/nateon/                                      *
 *                                                                         *
 *   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 3 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.             *
 ***************************************************************************/

#ifndef CHATVIEW_H
#define CHATVIEW_H

#include <kextsock.h>
#include <qtextedit.h>
#include <kdebug.h>
#include <qpushbutton.h>
#include <kurl.h>
#include <qtimer.h>
#include <klocale.h>
#include <qfiledialog.h>
#include <qdir.h>
#include <qstringlist.h>
#include <qlabel.h>
#include <qfontdialog.h>
#include <kconfig.h>
#include <kfontdialog.h>
#include <knotifyclient.h>
#include <qcolordialog.h>
#include <qaction.h>
#include <khelpmenu.h>
#include <kaboutdata.h>

#include "chatviewinterface.h"
#include "../network/knateonbuffer.h"

class QTextEdit;
class QPuchButton;
class KExtendedSocket;
class QTimer;
class Emoticon;
class QFileDialog;
class QDir;
class SendFile;
class QStringList;
class SendFileInfo;
class Common;
class ConfirmSaveLog;
class CurrentAccount;
class Buddy;
class GroupList;
class BuddyList;
class KNateonBuffer;
class EmoticonSelector;
class AddBuddySelector;
class NOMHTTPProxy;

class ChatView: public ChatQW
{
Q_OBJECT
public:
	ChatView(QWidget *parent = 0, const char *name = 0);
	~ChatView();
	bool isEmpty() const;
  
	const QString getServer() const             { return m_sSS_Server; }
	const int getPort() const                   { return m_nSS_Port; }
	const QString getLogFileName() const        { return m_sLogFileName; }
	const int getTID() const                    { return m_nTID; }
	const QString getAuthKey() const            { return m_sAuthKey; }
	const QString getID() const                 { return m_sID; }
	// const QString getNickName() const           { return m_sNickName; }
	// const QString getName() const               { return m_sName; }
	const QString getEncryptType() const        { return m_sEncryptType; }
	const QString getPublicKey() const          { return m_sPublicKey; }
	const QString getPVer() const               { return m_sPVer; }
	const int getDeviceType() const             { return m_nDevice; }
    // const int getP2PPort() const                { return nP2PPort; }
	const bool isCrypt() const                  { return bCrypt; }
	const QStringList getBuddyIDList() const;
	const QString getChatLog() const            { return sChatSaveLog; }

	/*! 채팅 로그 저장 */
	void addChatLog(const QString& sLog);
	void addChatLog( QString &sID, QString &sMessage ); /*! 비 버디 대화 */
	void addChatLog( QString &sName, QString &sNick, QString &sMessage );
	void addChatLog2( QString &sName, QString &sNick, QString &sMessage ); /*! 부재중 메시지 */
	
	void setServer(QString m_sServer)           { m_sSS_Server = m_sServer; }
	void setPort(int m_nPort)                   { m_nSS_Port = m_nPort; }
	void setLogFileName(QString m_sFileName)    { m_sLogFileName = m_sFileName; }
	void setTID(int m_TID)                      { m_nTID = m_TID; }
	void setAuthKey(QString m_AuthKey)          { m_sAuthKey = m_AuthKey; }
	void setID(QString m_ID)                    { m_sID = m_ID; }
	// void setNickName(QString m_NickName)        { m_sNickName = m_NickName; }
	// void setName(QString m_Name)                { m_sName = m_Name; }
	void setEncryptType(QString m_EncryptType)  { m_sEncryptType = m_EncryptType; }
	void setPublicKey(QString m_PublicKey)      { m_sPublicKey = m_PublicKey; }
	void setPVer(QString m_PVer)                { m_sPVer = m_PVer; }
	void setDeviceType(int m_DeviceType)        { m_nDevice = m_DeviceType; }
    // void setP2PPort(int P2PPort)                { nP2PPort = P2PPort; }
	void setCrypt(bool Crypt)                   { bCrypt = Crypt; }
	void setCurrentAccount( CurrentAccount *pCurrentAccount );
  
	const QPtrList<Buddy>& getBuddyList() const { return m_BuddyList; };
  
    /*! 기본으로 INVT를 보낸다. */
	void addBuddy(Buddy *pBuddy);
    /*! bQuit가 true면 INVT를 보내게 된다. */
	void addBuddy( Buddy *pBuddy, bool bQuit);
  
	/*! 버디 ID로 추가 */
	void addBuddy(const QString &sID, bool bQuit);
  
	Buddy* getBuddyByID(QString sID);
  
    /*! 채팅창 대화 내용보기 */
	/*! 보내는 메시지 보이기 */
	void addChatView( QString m_Msg );
	void addChatView( QFont &pFont, QColor &pColor, QString &sName, QString &sNick, QString &sMessage );
	void addChatViewAway( QFont &pFont, QColor &pColor, QString &sName, QString &sNick, QString &sMessage );
	void addChatViewBody( QFont &pFont, QColor &pColor, QString &sHeader, QString &sMessage );
	
	/*! 받은 메시지 보이기 */
	void addChatView( QString &sFontName, QString &sFontAttr, QString &sHEXColor, QString &sName, QString &sNick, QString &sMessage, bool bAway = FALSE );
	void addChatView( QString &sFontName, QString &sFontAttr, QString &sHEXColor, QString &sID, QString &sMessage, bool bAway = FALSE ); /*! 비 버디 */
	void addChatViewBody( QString &sFontName, QString &sFontAttr, QString &sHEXColor, QString &sHeader, QString &sMessage );
	
    /// SS Server Socket
	bool connectToServerSS();
	bool putRCONSS();
	bool putENTRSS();
    /* bool putENTRSS_Crypt(); */
	bool isConnectedSS() const { return ( m_pSSSocket->socketStatus() == KExtendedSocket::connected ); };
	int sendCommandSS(const QString& sPrefix, const QString &sText = "\r\n");
	int sendCommandSS_0(const QString& sPrefix, const QString &sText = "\r\n");
	int getTridSS() { return m_nTrid++; };
	void appendLogSS(const QString &m_Log);
	void disconnectFromServerSS(bool isTransfer=false);
	bool parseCommand(const QStringList& slCommand);
	void gotFILE_REQUEST(const QStringList& slCommand);
	void gotFILE_NACK( const QStringList& slCommand );
	void gotFILE_CANCEL( const QStringList& slCommand );
	void myCancel();
	
	void sendPing();
	void sendMessage(QString &sMsg);
	void sendAwayMessage();
    /* bool sendESSK(); */

	/*! 채팅 메시지 보내기 */
	void sendChatCommand(QFont &pFont, QColor &pColor, QString sCode, QString &sMessage );
	
    /*!
	  대화 메세지 Queue
      대화 상대가 모두 Quit 상태가 아닐때 메세지를 보낸다.
    */
	void addMessageQueue(const QString& csMsg) { slMessageQueue.append(csMsg); }
	// void clearMessageQueue() { slMessageQueue.clear(); }
	// const QStringList &getMessageQueue() { return slMessageQueue; }

	// void clearFileQueue() { slSendFileList.clear(); }
	// const QStringList &getFileQueue() { return slSendFileList; }
	
	bool isAllJoined();
  
	void setDisabled();
	void setEnabled();
  
	void updateGroupData(const GroupList* GroupList) { pGroupList = GroupList; }
	void updateBuddyData(const BuddyList* BuddyList) { pBuddyList = BuddyList; }
	void showInviteDialog();
	void updateUserStatus(QString sID, QString sStatus);
	void updateNickNameLabel();
	void show();
	void showNormal();
	// void showMinimized();
	void updateStatus(/* Buddy *pBuddy */);
  

	void putSuccessFileTransfer( SendFileInfo *pSendFileInfo );

	/*!
	 * 차단/차단해제 flag update
	 */
	void updateUserFlag(QString sID, QString sFlag);

	void updateStatusLabel();

	void sendFILE_CANCEL( const QString &sSSCookie );
	
	/*! 
	 * 버디리스트가 같은지 확인하는 함수
	 * 채팅창 띄울때 비교하기 위해서 사용.
	 */
	bool isEqualBuddyList( QStringList slBuddys );
	
	/*!
	 * 그룹 채팅 인가?
	 */
	bool isGroupChat() { return bGroupChat; }
	/*!
	 * hex 를 integer 로 변 
	 */
	int htoi( const char hex );
	
private :
    /// SS 서버IP
	QString m_sSS_Server;
    /// SS 서버포트
	int m_nSS_Port;
    /// AuthKey
	QString m_sAuthKey;
    /// 메신저 접속 ID
	QString m_sID;
    /// UTF8
	QString m_sCharEncodingType;
    /// P:Plain , C:Crypt
	QString m_sEncryptType;
    /// Encrypt 에서만 사용.
	QString m_sPublicKey;
    /// 1.1
	QString m_sPVer;
    /// 1:PC , 2:MG
	int m_nDevice;
    /// chatting 참여자 리스트
	QPtrList<Buddy> m_BuddyList;
    /// chatting 내용 저장을 위한 파일명
	QString m_sLogFileName;
    /// TID
	int m_nTID;
  
    /// SS서버 접속 소켓
	bool m_bWriteLocked;
	int m_nTrid;
	KExtendedSocket *m_pSSSocket;
  
	void writeDataSS(const QString& sData);
  
	KNateonBuffer m_Buffer;
  
	Emoticon*               pEmoticon;
	QPtrList<SendFileInfo>  m_SendFileInfoList;
  
	bool              bCrypt;
	bool              bTyping;
  
	QStringList       slMessageQueue;
	QTimer*           trMessageQueueTimer;
	QTimer*           trStatusLabelTimer;
  
	AddBuddySelector* pAddBuddy;
	EmoticonSelector* pEmoticonSelector;
  
	const BuddyList*  pBuddyList;
	const GroupList*  pGroupList;
	QString           sChatSaveLog;
  
	KConfig*          config;
	QString             caption_;
	CurrentAccount*       m_pCurrentAccount;
  
	bool bGroupChat;

	QStringList slSendFileList;

	ConfirmSaveLog *pConfirm;

	bool isNonBuddyChat;

	QString _BuddyStatusText;
	QString _MyStatusText;

	bool _BuddyDiable;

	QString sSaveStatus;

	QTimer *pTypeTimer;

	bool bTypeTimeOut;
	// bool bTypeNotice;
	
	bool bAlwaysTop;

	Common *m_pCommon;
	QString         sPicsPath;
	bool _MyDiable;
	bool bSave;
	
	/*! HTTP Proxy */
	NOMHTTPProxy *m_pHttpProxy;

protected:
	// void hideEvent ( QHideEvent *e );
	void moveEvent ( QMoveEvent *e );
	void closeEvent ( QCloseEvent * e );
	void dropEvent ( QDropEvent * e );
	void resizeEvent ( QResizeEvent * e );
	void showEvent ( QShowEvent * e );
  
public slots:
	virtual void slotSendFile();
	void slotSendFileList( const QStringList &slFiles );
	
private slots:
	void sendMSG();
	void dataReceivedSS();
	void socketError(int nError);
	void socketclosed(int nFlag);
	void slotSendTyping();
	void slotMessageQueueFail();
	void slotHideStatusLabel();
	void slotInviteDialog();
	void slotAddBuddies(const QString& csList);
	/*! 본인의 글자폰트 변경 */
	void slotFontDialog();
	void slotEmoticonDialog();
	void slotPutEmoticon( const QString &sText );
	/*! 본인의 글자색 변경 */
	void slotFontColorDialog();
  
    /*! 메뉴 */
	virtual void slotSave(); /*! 대화 저장 */
	virtual void slotFileFolder(); /*! 받은 파일 폴더 열기 */
	virtual void slotShowChatLog(); /*! 지난 대화 보기 */
	virtual void slotClose(); /*! 닫기 */
	virtual void slotInvite(); /*! 친구 초대 */
	virtual void slotSendMemo();
	virtual void slotShowProfile();
	virtual void slotAddBuddy();
	virtual void slotLock();
	virtual void slotOnline();
	virtual void slotAway();
	virtual void slotBusy();
	virtual void slotPhone();
	virtual void slotMeeting();
	virtual void slotOffline();
	virtual void slotChangeNick();
	virtual void slotEditMyProfile();
	virtual void slotAlwaysTop();
	virtual void slotSetup();
	virtual void slotGoNateonHome();
	virtual void slotGoCyworldHome();
	virtual void slotGoNateDotComHome();
	virtual void slotGoHelp();
	virtual void slotGoNateonMiniHompy();
	virtual void slotGoHotTip();
	virtual void slotGoFaq();
	virtual void slotInfo();

	/*! 입력중 타임 아웃 */
	void slotTypeTimeOut();
	
protected slots :
	virtual void connectionSuccess();
	void slotChangeStatus( int );
	void slotBuddyChangeNick();
  
signals :
    /*! 디버그 메시지 출력. */
	void OutgoingMessage(const QString& csMsg);
	void IncomingMessage(const QString& csMsg);
  
	void statusMessage( QString sMessage, int connectStatus );
	void BuddyAdded( Buddy* pBuddy );
	void disconnectedSS();
	void putINVT( ChatView* );
	void newConnectSS( ChatView* );
	void sendFile( SendFileInfo* );
	void sendRECQNEW( ChatView*, SendFileInfo* );
	void hideChat(ChatView*, bool);
	void saveChatLog(ChatView*, bool);
	void updateInviteData(ChatView*);
	void putINVT_Invite( ChatView*, QStringList& );
    /*! WHSP NACK를 받았을때... */
	void cancelReceive( const QStringList& );
	void cancelReceiveAll( const QStringList& );
	void gotChatMessage( const QStringList& );
	void showDownDir();
	void showChatLog( const ChatView* );
	void sendMemo( const QString & );
	void addBuddy();
	void lockToggle( const QString & );
	void changeNick();
	void showSetup();
	void cancelFileTransfer( const QString & );
};

#endif
