package cn.tee3.avd;
/**
 * Created by bob.liu on 2015/8/24.
 */
import android.os.Handler;

import java.util.List;

import javax.annotation.Nullable;

/**
 * 房间中聊天模块接口.
 *
 * 房间聊天模块定义房间中公聊和私聊等聊天功能接口。
 */
public class MChat extends Module {
    private static final String TAG = "MChat";

    /**
     * 聊天消息结构.
     *
     * 聊天消息定义了一次传输聊天的信息。
     */
    public static class Message{
        private int timestamp;                          /**< 消息时间戳，对应用层是本地时间，传输中用GMT时间 */
        private String fromId;                          /**< 消息发送者Id */
        private String fromName;                        /**< 消息发送者名 */
        private String message;                         /**< 消息内容 */

        public Message(int timestamp, String fromId, String fromName, String message) {
            this.timestamp = timestamp;
            this.fromId = fromId;
            this.fromName = fromName;
            this.message = message;
        }
        public int getTimeStamp() { return this.timestamp; }
        public String getFromId() { return this.fromId; }
        public String getFromName() { return this.fromName; }
        public String getMessage() { return this.message; }
        public void setMessage(String value) { this.message = value; }
        @Override
        public String toString() {
            return "Message: ts=" + this.timestamp + ",from="+this.fromId + ",msg="+this.message;
        }
    }

    /**
     * 房间中聊天模块回调接口.
     *
     * 聊天模块回调接口定义了房间中聊天相关的通知。
     */
    public static interface Listener {
        /// 通知
        /** 接收到公聊消息通知
         *
         * @param[in] message 消息内容。
         * @note 当用户发送公聊消息后，房间内所有用户除发送者外都将接收到此通知。
         * @sa Message
         * @sa sendPublicMessage
         */
        public void onPublicMessage(Message message);
        /** 接收到私聊消息通知
         *
         * @param[in] message 消息内容。
         * @note 当用户发送私聊消息后，只有消息目的用户接收到此消息通知。
         * @sa Message
         * @sa sendPrivateMessage
         */
        public void onPrivateMessage(Message message);
    }
    ///
    private long nativeListener = 0;
    @Nullable private Listener listener4cb = null;
    @Nullable private Handler listenerHandler = null;
    @Nullable private SDKListener listener4native = null;
    ///
    /** 获取房间内聊天模块接口
     *
     * @param[in] room 房间对象。
     * @return 聊天模块接口。
     * @sa Room
     */
    @Nullable public static MChat getChat(Room room) {
        return (MChat)room.getModule(Type.chat);
    }
    protected MChat(Room room) {
        super(room, Type.chat, room.nativegetMChat());
        Tlog.d(TAG, "MChat, nativeChat:" + this.nativeobj);
        initNativeListener();
    }
    @Override
    protected void dispose() {
        if (0 != this.nativeListener) {
            nativeFreeListener(this.nativeListener);
        }
        this.nativeListener = 0;
        this.nativeobj = 0;
    }

    /** 设置房间聊天模块回调接口
     *
     * @param[in] listener 聊天模块回调接口指针。
     * @return 返回错误代码。
     * @sa Listener
     */
    public boolean setListener(Listener listener) {
        Tlog.d(TAG, "setListener, listener:" +listener+",listener4native="+this.listener4native+",listenerHandler="+this.listenerHandler);
        this.listener4cb = listener;
        if (null != listener) {
            initNativeListener();
        }
        Tlog.v(TAG, "setListener, out:");
        return true;
    }

    public void initNativeListener(){
        if (0 != this.nativeListener) {
            return;
        }
        initHandler();
        this.nativeListener = nativeCreateListener(listener4native);
        Tlog.d(TAG, "initNativeListener, Create nativelistener:" + nativeListener);
    }
    /** 发送公聊消息
     *
     * @param[in] message 消息内容。
     *
     * @return 返回错误代码。
     */
    public int sendPublicMessage(String message) {
        Tlog.d(TAG, "MChat, sendPublicMessage, message:"+message);
        return nativesendPublicMessage(message);
    }
    /** 发送私聊消息
     *
     * @param[in] message 消息内容。
     * @param[in] toId 私聊消息目的用户Id。
     *
     * @return 返回错误代码。
     */
    public int sendPrivateMessage(String message, String toId) {
        Tlog.d(TAG, "MChat, sendPrivateMessage, message:"+message+",toId:"+toId);
        return nativesendPrivateMessage(message, toId);
    }
    //
    /** 获取公聊历史消息记录
     *
     * @param[in] latest 是否是最新记录（即反序）。
     * @param[in] begindex 消息起始索引。
     * @param[in,out] ncount 请求消息数量；实际消息返回数量。
     *
     * @return 返回消息列表。
     */
    public List<Message> getPublicHistoryMessage(boolean latest, int begindex, int ncount) {
        Tlog.d(TAG, "MChat, getPublicHistoryMessage, begindex:"+begindex +",ncount:" + ncount);
        return nativegetPublicHistoryMessage(latest, begindex, ncount);
    }
    /** 获取私聊聊历史消息记录
     *
     * @param[in] userId 聊天对方的用户Id。
     * @param[in] latest 是否是最新记录（即反序）。
     * @param[in] begindex 消息起始索引。
     * @param[in,out] ncount 请求消息数量；实际消息返回数量。
     *
     * @return 返回消息列表。
     */
    public List<Message> getPrivateHistoryMessage(String userId, boolean latest, int begindex, int ncount) {
        Tlog.d(TAG, "MChat, getPrivateHistoryMessage, begindex:"+begindex +",ncount:" + ncount);
        return nativegetPrivateHistoryMessage(userId, latest, begindex, ncount);
    }
    ///
    private native long nativeCreateListener(Listener listener);
    private native void nativeFreeListener(long nativeListener);
    private native int nativesendPublicMessage(String message);
    private native int nativesendPrivateMessage(String message, String userId);
    private native List<Message> nativegetPublicHistoryMessage(boolean latest, int tsbegin, int ncount);
    private native List<Message> nativegetPrivateHistoryMessage(String userId, boolean latest, int tsbegin, int ncount);

    ///
    private static final int msg_onPublicMessage = 1;
    private static final int msg_onPrivateMessage = 2;
    private boolean initHandler() {
        if (null == listener4native) {
            listener4native = new SDKListener();
        }
        if (null != listenerHandler) {
            return true;
        }
        AVDEngine.runOnLoopThreadSync(new Runnable() {
            @Override
            public void run() {
                initHandler_main();
            }
        });
        return true;
    }
    private boolean initHandler_main() {
        this.listenerHandler = new Handler() {
            @Override
            public void handleMessage(android.os.Message msg) {
                Tlog.v(TAG, "handleMessage, msg:" + msg.toString());
            if (null == listener4cb) {
                super.handleMessage(msg);
                return;
            }
            switch (msg.what) {
                case msg_onPublicMessage:
                    listener4cb.onPublicMessage((Message) msg.obj);
                    break;
                case msg_onPrivateMessage:
                    listener4cb.onPrivateMessage((Message) msg.obj);
                    break;
            }
            super.handleMessage(msg);
            }
        };
        return true;
    }
    private class SDKListener implements Listener {
        public SDKListener() {
        }
        @Override
        public void onPublicMessage(Message message) {
            if (null == listenerHandler) {
                return ;
            }
            android.os.Message msg = android.os.Message.obtain(listenerHandler,msg_onPublicMessage, message);
            listenerHandler.sendMessage(msg);
        }
        @Override
        public void onPrivateMessage(Message message) {
            if (null == listenerHandler) {
                return ;
            }
            android.os.Message msg = android.os.Message.obtain(listenerHandler,msg_onPrivateMessage, message);
            listenerHandler.sendMessage(msg);
        }
    }
}
