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

import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;

import java.util.List;
import java.util.UUID;

/**
 * 白板模块接口.
 */
public class MWhiteboard extends Module {
    private static final String TAG = "MWhiteboard";

    private WhiteboardView mBoardView;
    private static MWhiteboard mWhiteboard;
    private Whiteboard whiteboard;
    private Whiteboard remoteWhiteboard;
    private String mWhiteboardId = "";
    private static MAnnotationInternal annotationInternal;

    private long nativeListener = 0;
    private Listener listener4cb = null;
    private Handler listenerHandler = null;
    private SDKListener listener4native = null;
    private Context context;

    private boolean isWhiteboardWork;
    private boolean isShowToolbar = true;

    protected MWhiteboard(Room room) {
        super(room, Type.MWhiteboard, room.nativegetMWhiteboard());
        Tlog.d(TAG, "MWhiteboard, nativegetMWhiteboard:" + this.nativeobj);
        initNativeListener();
        isWhiteboardWork = false;
    }

    /**
     * 获取房间白板模块
     *
     * @return 返回白板模块接口指针。
     * @param[in] room 房间对象指针。
     */
    public static MWhiteboard getWhiteboard(Room room) {
        mWhiteboard = (MWhiteboard) room.getModule(Type.MWhiteboard);
        annotationInternal = mWhiteboard.getAnnotation();
        return mWhiteboard;
    }

    public Whiteboard getWhiteboardParams() {
        return whiteboard;
    }

    private void shareBoard() {
        if (mBoardView == null) {
            return;
        }
        List<Whiteboard> whiteboardList = getWhiteBoards();
        if (whiteboardList == null || !whiteboardList.contains(whiteboard)) {
            mWhiteboard.createBoard(whiteboard);
            mWhiteboard.shareBoard(mWhiteboardId);
            if (listener4cb != null) {
                listener4cb.onShareBoardNotify(whiteboard);
            }
        }

        mBoardView.setParams(whiteboard, annotationInternal, true);
        showOrHideWhiteboardView(true);
    }

    public boolean hasWhiteboardShared() {
        return isWhiteboardWork;
    }

    public String createLocalWhiteboard(String title, String desc, int color) {
//        if (hasWhiteboardShared()) {
//            Toast toast = Toast.makeText(context, "当前会议一次只允许一人进行共享！", Toast.LENGTH_LONG);
//            toast.setGravity(Gravity.CENTER, 0, 0);
//            toast.show();
//            return;
//        }
        Tlog.d(TAG, "MWhiteboard.createLocalWhiteboard()");
        isWhiteboardWork = true;
        if (TextUtils.isEmpty(mWhiteboardId)) {
            mWhiteboardId = UUID.randomUUID().toString();
        }

        if (mBoardView == null) {
            return mWhiteboardId;
        }

        if (whiteboard == null) {
            mBoardView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mBoardView.getWidth() == 0 || mBoardView.getHeight() == 0) {
                        Tlog.w(TAG, "Create whiteboard params error, width=" + mBoardView.getWidth() + ", height=" + mBoardView.getHeight());
                    } else {
                        Tlog.i(TAG, "Create whiteboard success, width=" + mBoardView.getWidth() + ", height=" + mBoardView.getHeight());
                    }

                    mBoardView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    whiteboard = new Whiteboard(mWhiteboardId, getUserManager().getSelfUserId(), title, desc, "", mBoardView.getWidth(),
                            mBoardView.getHeight(), 0, (byte) (Color.alpha(color)), (byte) (Color.red(color)), (byte) (Color.green(color)), (byte) (Color.blue(color)));
                    shareBoard();
                }
            });
        } else {
            whiteboard.set_title(title);
            whiteboard.set_description(desc);
            whiteboard.set_a((byte) (Color.alpha(color)));
            whiteboard.set_r((byte) (Color.red(color)));
            whiteboard.set_g((byte) (Color.green(color)));
            whiteboard.set_b((byte) (Color.blue(color)));
            shareBoard();
        }
        mBoardView.requestLayout();
        showOrHideWhiteboardView(true);
        return mWhiteboardId;
    }

    public String createLocalWhiteboard(String title, String desc, String remoteBgUrl, int color) {
//        if (hasWhiteboardShared()) {
//            Toast toast = Toast.makeText(context, "当前会议一次只允许一人进行共享！", Toast.LENGTH_LONG);
//            toast.setGravity(Gravity.CENTER, 0, 0);
//            toast.show();
//            return;
//        }
        Tlog.d(TAG, "MWhiteboard.createLocalWhiteboard()");
        isWhiteboardWork = true;
        if (TextUtils.isEmpty(mWhiteboardId)) {
            mWhiteboardId = UUID.randomUUID().toString();
        }

        if (mBoardView == null) {
            return mWhiteboardId;
        }

        if (whiteboard == null) {
            mBoardView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mBoardView.getWidth() == 0 || mBoardView.getHeight() == 0) {
                        Tlog.w(TAG, "Create whiteboard params error, width=" + mBoardView.getWidth() + ", height=" + mBoardView.getHeight());
                    } else {
                        Tlog.i(TAG, "Create whiteboard success, width=" + mBoardView.getWidth() + ", height=" + mBoardView.getHeight());
                    }

                    mBoardView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    whiteboard = new Whiteboard(mWhiteboardId, getUserManager().getSelfUserId(), getUserManager().getSelfUser().getUserName(), title, desc, remoteBgUrl, mBoardView.getWidth(),
                            mBoardView.getHeight(), 0, (byte) (Color.alpha(color)), (byte) (Color.red(color)), (byte) (Color.green(color)), (byte) (Color.blue(color)));
                    shareBoard();
                }
            });
        } else {
            whiteboard.set_title(title);
            whiteboard.set_description(desc);
            whiteboard.set_remoteBgUrl(remoteBgUrl);
            whiteboard.set_a((byte) (Color.alpha(color)));
            whiteboard.set_r((byte) (Color.red(color)));
            whiteboard.set_g((byte) (Color.green(color)));
            whiteboard.set_b((byte) (Color.blue(color)));
            shareBoard();
        }
        mBoardView.requestLayout();
        showOrHideWhiteboardView(true);
        return mWhiteboardId;
    }

    public boolean hasLocalWhiteboardShared() {
        if (whiteboard != null) {
            List<Whiteboard> boards = getSharedWhiteBoards();
            if (boards == null || boards.size() == 0) {
                return false;
            }
            for (Whiteboard whiteboard : boards) {
                if (whiteboard._boardId.equals(mWhiteboardId)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean isWhiteboardShared(String boardId) {
        if (TextUtils.isEmpty(boardId)) {
            return false;
        }
        List<Whiteboard> boards = getSharedWhiteBoards();
        if (boards == null || boards.size() == 0) {
            return false;
        }
        for (Whiteboard whiteboard : boards) {
            if (whiteboard._boardId.equals(boardId)) {
                return true;
            }
        }
        return false;
    }

    public void rebuildLocalWhiteboard() {
        isWhiteboardWork = true;
        mWhiteboard.createBoard(whiteboard);
        mWhiteboard.shareBoard(mWhiteboardId);
//        mBoardView.reConnect();
    }

    private void createRemoteWhiteboard(String boardId) {
        List<Whiteboard> whiteboards = nativegetWhiteBoards();
        if (whiteboards == null) {
            isWhiteboardWork = false;
            Tlog.e(TAG, "createRemoteWhiteboard -> whiteboard not exist_01");
            return;
        }
        for (Whiteboard whiteboard : whiteboards) {
            if (whiteboard._boardId.equals(boardId)) {
                isWhiteboardWork = true;
                String userName = getUserManager().getUser(whiteboard.get_ownId()).getUserName();
                whiteboard.set_ownName(userName);
                remoteWhiteboard = whiteboard;
                if (mBoardView != null) {
                    mBoardView.setParams(remoteWhiteboard, annotationInternal, false);
                    showOrHideWhiteboardView(true);
                }
                return;
            }
        }
        Tlog.e(TAG, "createRemoteWhiteboard -> whiteboard not exist_02");
        isWhiteboardWork = false;
    }

    private void createRemoteWhiteboard() {
        if (mBoardView == null) {
            return;
        }
        List<Whiteboard> boards = getSharedWhiteBoards();
        if (boards.size() > 0) {
            if (!boards.get(0).getBoardId().equals(mWhiteboardId)) {
                remoteWhiteboard = boards.get(0);
                remoteWhiteboard.set_ownName(getUserManager().getUserName(remoteWhiteboard.get_ownId()));
                mBoardView.setParams(remoteWhiteboard, annotationInternal, false);
                if (listener4cb != null) {
                    Tlog.d(TAG, "MWhiteboard.createRemoteWhiteboard()");
                    listener4cb.onShareBoardNotify(remoteWhiteboard);
                }
            } else {
                mBoardView.setParams(whiteboard, annotationInternal, true);
            }
            isWhiteboardWork = true;
            showOrHideWhiteboardView(true);
        }else {
            isWhiteboardWork = false;
        }
    }

    public void onUserLeave(User user) {
        List<Whiteboard> whiteBoards = getWhiteBoards();
        if (whiteBoards == null || whiteBoards.size() == 0) {
            return;
        }

        for (Whiteboard whiteboard : whiteBoards) {
            if (whiteboard._ownId.equals(user.getUserId())) {
                closeRemoteBoard(whiteboard._boardId);
                nativeremoveBoard(whiteboard._boardId);
                continue;
            }
        }
    }

    public boolean isVisible() {
        if (mBoardView == null) {
            return false;
        }
        return mBoardView.getVisibility() == View.VISIBLE;
    }

    public boolean isDrawToolVisible() {
        if (mBoardView == null) {
            return false;
        }
        return mBoardView.toolView.ll_draw_tool.getVisibility() == View.VISIBLE;
    }

    public MWhiteboard onAttachView(WhiteboardView view) {
        if (view == null) {
            Tlog.e(TAG, "MWhiteboard.onAttachView() , WhiteboardView is null !");
            return this;
        }
        Tlog.d(TAG, "MWhiteboard.onAttachView()");
        this.context = view.getViewContext();
        mBoardView = view;
        mBoardView.setUserId(getUserManager().getSelfUserId())
                .setAnnotationInternal(annotationInternal);
        createRemoteWhiteboard();   /** 检查是否有共享的白板并创建 */
        return this;
    }

    public WhiteboardView getWhiteboardView() {
        return mBoardView;
    }

    /************************************************************************************************************************************************************************/

    @Override
    public void dispose() {
        Tlog.d(TAG, "MWhiteboard.dispose()");
        if (mBoardView != null && mBoardView.drawView != null) {
            mBoardView.drawView.release();
        }
        if (whiteboard != null && hasLocalWhiteboardShared()) {
            nativecloseBoard(mWhiteboardId);
            nativeremoveBoard(mWhiteboardId);
        }
        if (0 != this.nativeListener) {
            nativeFreeListener(this.nativeListener);
        }
        this.nativeListener = 0;
        this.nativeobj = 0;

        if (annotationInternal != null) {
            annotationInternal.freeListener();
            annotationInternal = null;
        }

        release();
    }

    /**
     * 释放资源
     */
    public void release() {
        Tlog.d(TAG, "MWhiteboard.release()");
        mBoardView = null;
        mWhiteboard = null;
        whiteboard = null;
        remoteWhiteboard = null;
        annotationInternal = null;
        mWhiteboardId = "";
        nativeListener = 0;

        listener4cb = null;
        listenerHandler = null;
        listener4native = null;
        context = null;
        isWhiteboardWork = false;
        isShowToolbar = true;
    }

    public MAnnotationInternal getAnnotation() {
        long nativeannobj = nativegetAnnotation();
        if (0 != nativeannobj) {
            annotationInternal = new MAnnotationInternal(nativeannobj);
        }
        return annotationInternal;
    }

    public int createBoard(Whiteboard whiteboard) {
        Tlog.d(TAG, "createBoard ");
        int ret = nativecreateBoard(whiteboard);
        return ret;
    }

    public int shareBoard(String boardId) {
        Tlog.d(TAG, "shareBoard ");
        int ret = nativeshareBoard(boardId);
        return ret;
    }

    public void closeRemoteBoard(String boardId) {
        Tlog.d(TAG, "closeRemoteBoard, boardId=" + boardId);
        if (mBoardView == null) {
            return;
        }
        remoteWhiteboard = null;
        mBoardView.clearPaint();
        if (hasLocalWhiteboardShared()) {
            mBoardView.setParams(whiteboard, annotationInternal, true);
            showOrHideWhiteboardView(true);
        } else {
            isWhiteboardWork = false;
            showOrHideWhiteboardView(false);
        }
    }

    public void closeLocalBoard() {
        Tlog.d(TAG, "closeLocalBoard ");
        if (hasLocalWhiteboardShared() && mBoardView != null) {
            nativecloseBoard(mWhiteboardId);
            listener4cb.onCloseBoardNotify(whiteboard._boardId);
            mBoardView.clearPaint();
            if (remoteWhiteboard != null) {
                mBoardView.setParams(remoteWhiteboard, annotationInternal, false);
                showOrHideWhiteboardView(true);
            } else {
                isWhiteboardWork = false;
                showOrHideWhiteboardView(false);
            }
        }
    }

    private void showOrHideWhiteboardView(boolean isShow) {
        if (mBoardView == null) {
            return ;
        }
        if (mBoardView.getVisibility() == View.VISIBLE && !isShow) {
            mBoardView.setVisibility(View.GONE);
            mBoardView.setClickable(false);
            mBoardView.setFocusable(false);
        } else if ((mBoardView.getVisibility() == View.INVISIBLE || mBoardView.getVisibility() == View.GONE) && isShow) {
            mBoardView.setVisibility(View.VISIBLE);
            mBoardView.setClickable(true);
            mBoardView.setFocusable(true);
            if (mBoardView.toolView != null && mBoardView.drawView != null) {
                if (isShowToolbar) {
                    mBoardView.toolView.setVisibility(View.VISIBLE);
                    mBoardView.toolView.setDrawToolState(true);
                    mBoardView.toolView.ll_draw_tool.setVisibility(View.VISIBLE);
                    mBoardView.toolView.ll_set_color.setVisibility(View.GONE);
                    mBoardView.drawView.setDrawToolViewVisible(true);
                } else {
                    mBoardView.toolView.setVisibility(View.GONE);
                }
            }
        }
        if (mBoardView.toolView != null) {
            if (hasLocalWhiteboardShared() && mBoardView.getWhiteboard()._boardId.equals(mWhiteboardId)) {
                mBoardView.toolView.ll_laser_pen.setVisibility(View.VISIBLE);
            } else {
                mBoardView.toolView.ll_laser_pen.setVisibility(View.GONE);
            }
        }
    }

    public String getLocalWhiteboardId() {
        if (mBoardView == null || mBoardView.getWhiteboard() == null) {
            return "";
        }
        return mBoardView.getWhiteboard().getBoardId();
    }

    public int showWhiteboard(String boardId) {
        if (TextUtils.isEmpty(boardId)) {
            return ErrorCode.Err_Invalid_Arg;
        } else if (mBoardView == null) {
            return ErrorCode.Err_Not_Initialized;
        }

        if (isWhiteboardShared(boardId)) {
            List<Whiteboard> boards = getSharedWhiteBoards();
            for (Whiteboard whiteboard : boards) {
                if (whiteboard._boardId.equals(boardId)) {
                    mBoardView.setParams(whiteboard, annotationInternal, true);
                    showOrHideWhiteboardView(true);
                }
            }
            return ErrorCode.AVD_OK;
        } else {
            return ErrorCode.Err_Not_Initialized;
        }
    }

    public MWhiteboard showToolbar(boolean isShow) {
        this.isShowToolbar = isShow;
        if (mBoardView != null) {
            mBoardView.showToolbar(isShow);
        }
        return this;
    }

    public void removeBoard(String id) {
        Tlog.d(TAG, "MWhiteboard, removeBoard ");
        nativeremoveBoard(id);
    }

    public int updateBoard(String id, Whiteboard wb) {
        Tlog.d(TAG, "MWhiteboard, updateBoard ");
        return nativeupdateBoard(id, wb);
    }

    public int setBackground(String id, String filePath) {
        Tlog.d(TAG, "MWhiteboard, setImageResource ");
        return nativesetBackgroundPath(id, filePath);
    }

    public int setBackground(String id, char r, char g, char b, char a) {
        Tlog.d(TAG, "MWhiteboard, setImageResource ");
        return nativesetBackground(id, r, g, b, a);
    }

    public int setWidth(String id, int w) {
        Tlog.d(TAG, "MWhiteboard, setWidth ");
        return nativesetWidth(id, w);
    }

    public int setHeight(String id, int h) {
        Tlog.d(TAG, "MWhiteboard, setHeight ");
        return nativesetHeight(id, h);
    }

    public int attachBoard(String bid, long winId) {
        Tlog.d(TAG, "MWhiteboard, attachBoard ");
        return nativeattachBoard(bid, winId);
    }

    public int detachBoard(String bid) {
        Tlog.d(TAG, "MWhiteboard, detachBoard ");
        return nativedetachBoard(bid);
    }

    public List<Whiteboard> getWhiteBoards() {
        return nativegetWhiteBoards();
    }

    public List<Whiteboard> getSharedWhiteBoards() {
        return nativegetSharedWhiteBoards();
    }

    private static final int msg_onCreateBoardNotify = 1;
    private static final int msg_onRemoveBoardNotify = 2;
    private static final int msg_onUpdateBoardNotify = 3;
    private static final int msg_onShareBoardNotify = 4;
    private static final int msg_onCloseBoardNotify = 5;
    private static final int msg_onAnnotationDelNotifiy = 6;
    private static final int msg_onAnnotationAddNotifiy = 7;
    private static final int msg_onAnnotationUpdateNotifiy = 8;

    private native long nativeCreateListener(Listener listener);

    private native void nativeFreeListener(long nativeListener);

    private native long nativegetAnnotation(String id);

    private native int nativecreateBoard(Whiteboard wb);

    private native int nativeshareBoard(String boardId);

    private native void nativecloseBoard(String id);

    private native void nativeremoveBoard(String id);

    private native int nativeupdateBoard(String id, Whiteboard wb);

    private native int nativesetBackgroundPath(String id, String filePath);

    private native int nativesetBackground(String id, char r, char g, char b, char a);

    private native int nativesetWidth(String id, int w);

    private native int nativesetHeight(String id, int h);

    private native int nativeattachBoard(String bid, long winId);

    private native int nativedetachBoard(String bid);

    private native long nativegetAnnotation();

    private native List<Whiteboard> nativegetWhiteBoards();

    private native List<Whiteboard> nativegetSharedWhiteBoards();

    /**
     * WhiteboardView 触摸事件监听
     *
     * @param listener
     */
    public void setOnTouchEventListener(WhiteboardView.IOnTouchEventListener listener) {
        if (listener != null && mBoardView != null) {
            mBoardView.setOnTouchEventListener(listener);
        }
    }

    /**
     * WhiteboardView 触摸事件监听
     *
     * @param listener
     */
    public void setOnDrawToolVisibleListener(WhiteboardView.IDrawToolbarListener listener) {
        if (listener != null && mBoardView != null) {
            mBoardView.setDrawToolViewVisibleListener(listener);
        }
    }

    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(Looper.getMainLooper()) {
            public void handleMessage(Message msg) {
                Tlog.v(TAG, "handleMessage, msg:" + msg.toString());
                switch (msg.what) {
                    case msg_onCreateBoardNotify:
                        Whiteboard whiteboardCreate = (Whiteboard) msg.obj;
                        Tlog.d(TAG, "MWhiteboard.createWhiteboard:" + (whiteboardCreate == null ? "remoteWhiteboard == null" : (whiteboardCreate.toString())));
                        if (listener4cb != null) {
                            listener4cb.onCreateBoardNotify(whiteboardCreate);
                        }
                        break;
                    case msg_onRemoveBoardNotify:
                        Tlog.d(TAG, "MWhiteboard.removeWhiteboard:" + (remoteWhiteboard == null ? "" : (remoteWhiteboard.getBoardId())));
                        closeRemoteBoard((String) msg.obj);
                        if (listener4cb != null) {
                            listener4cb.onRemoveBoardNotify((String) msg.obj);
                        }
                        break;
                    case msg_onUpdateBoardNotify:
                        Tlog.d(TAG, "MWhiteboard.updateWhiteboard:" + (remoteWhiteboard == null ? "" : (remoteWhiteboard.getBoardId())));
                        if (listener4cb != null) {
                            listener4cb.onUpdateBoardNotify((Whiteboard) msg.obj);
                        }
                        break;
                    case msg_onShareBoardNotify:
                        Whiteboard whiteboardShare = (Whiteboard) msg.obj;
                        createRemoteWhiteboard(whiteboardShare.getBoardId());
                        Tlog.d(TAG, "MWhiteboard.shareWhiteboard:" + (remoteWhiteboard == null ? "" : (remoteWhiteboard.getBoardId())));
                        if (listener4cb != null) {
                            listener4cb.onShareBoardNotify(whiteboardShare);
                        }
                        break;
                    case msg_onCloseBoardNotify:
                        if (remoteWhiteboard == null) {
                            return;
                        }
                        Tlog.d(TAG, "MWhiteboard.closeWhiteboard:" + (remoteWhiteboard == null ? "" : (remoteWhiteboard.getBoardId())));
                        closeRemoteBoard((String) msg.obj);
                        if (listener4cb != null) {
                            listener4cb.onCloseBoardNotify((String) msg.obj);
                        }
                        break;
                }
            }
        };
        return true;
    }

    /**
     * 设置白板模块回调接口
     *
     * @return 返回错误代码。
     * @param[in] listener 白板模块接口指针。
     * @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.d(TAG, "setListener, Create nativelistener:" + nativeListener);
        }
        return true;
    }

    public void initNativeListener() {
        if (0 != this.nativeListener) {
            return;
        }
        initHandler();
        this.nativeListener = nativeCreateListener(listener4native);
        Tlog.d(TAG, "initNativeListener, Create nativelistener:" + nativeListener);
    }


    /**
     * 白板回调接口
     */
    public interface Listener {
        void onCreateBoardNotify(Whiteboard board);

        void onRemoveBoardNotify(String bid);

        void onUpdateBoardNotify(Whiteboard board);

        void onShareBoardNotify(Whiteboard board);

        void onCloseBoardNotify(String bid);
    }

    private class SDKListener implements Listener {

        public SDKListener() {
        }

        @Override
        public void onCreateBoardNotify(Whiteboard board) {
            Tlog.d(TAG, "SDKListener -> onCreateBoardNotify()");
            if (null == listenerHandler) {
                return;
            }
            Message msg = Message.obtain(listenerHandler, msg_onCreateBoardNotify, board);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onRemoveBoardNotify(String bid) {
            Tlog.d(TAG, "SDKListener -> onRemoveBoardNotify()");
            if (null == listenerHandler) {
                return;
            }
            Message msg = Message.obtain(listenerHandler, msg_onRemoveBoardNotify, bid);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onUpdateBoardNotify(Whiteboard board) {
            Tlog.d(TAG, "SDKListener -> onUpdateBoardNotify()");
            if (null == listenerHandler) {
                return;
            }
            Message msg = Message.obtain(listenerHandler, msg_onUpdateBoardNotify, board);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onShareBoardNotify(Whiteboard board) {
            Tlog.d(TAG, "SDKListener -> onShareBoardNotify()");
            if (null == listenerHandler) {
                return;
            }
            Message msg = Message.obtain(listenerHandler, msg_onShareBoardNotify, board);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onCloseBoardNotify(String bid) {
            Tlog.d(TAG, "MWhiteboard -> SDKListener -> onCloseBoardNotify()");
            if (null == listenerHandler) {
                return;
            }
            Message msg = Message.obtain(listenerHandler, msg_onCloseBoardNotify, bid);
            listenerHandler.sendMessage(msg);
        }
    }

    /**
     * 白板结构.
     */
    public static class Whiteboard {
        public String _boardId;
        public String _ownId;
        public String _ownName;
        public String _title;
        public String _description;
        public String _remoteBgUrl;
        public int _width;
        public int _height;
        public long _wndid;
        public int _a;
        public int _r;
        public int _g;
        public int _b;

        public Whiteboard(String _boardId, String _ownId, String _title, String _description, String _remoteBgUrl, int _width, int _height, long _wndid, int _a, int _r, int _g, int _b) {
            this._boardId = _boardId;
            this._ownId = _ownId;
            this._title = _title;
            this._description = _description;
            this._remoteBgUrl = _remoteBgUrl;
            this._width = _width;
            this._height = _height;
            this._wndid = _wndid;
            this._a = _a;
            this._r = _r;
            this._g = _g;
            this._b = _b;
        }

        public Whiteboard(String _boardId, String _ownId, String _ownName, String _title, String _description, String _remoteBgUrl, int _width, int _height, long _wndid, int _a, int _r, int _g, int _b) {
            this._boardId = _boardId;
            this._ownId = _ownId;
            this._ownName = _ownName;
            this._title = _title;
            this._description = _description;
            this._remoteBgUrl = _remoteBgUrl;
            this._width = _width;
            this._height = _height;
            this._wndid = _wndid;
            this._a = _a;
            this._r = _r;
            this._g = _g;
            this._b = _b;
        }

        public String get_ownId() {
            return _ownId;
        }

        public void set_ownId(String _ownId) {
            this._ownId = _ownId;
        }

        public String get_ownName() {
            return _ownName;
        }

        public void set_ownName(String _ownName) {
            this._ownName = _ownName;
        }

        public String getBoardId() {
            return _boardId;
        }

        public String get_remoteBgUrl() {
            return _remoteBgUrl;
        }

        public void set_remoteBgUrl(String _remoteBgUrl) {
            this._remoteBgUrl = _remoteBgUrl;
        }

        public String get_description() {
            return _description;
        }

        public void set_description(String _description) {
            this._description = _description;
        }

        public String get_boardId() {
            return _boardId;
        }

        public void set_boardId(String _boardId) {
            this._boardId = _boardId;
        }

        public String get_title() {
            return _title;
        }

        public void set_title(String _title) {
            this._title = _title;
        }

        public int get_width() {
            return _width;
        }

        public void set_width(int _width) {
            this._width = _width;
        }

        public int get_height() {
            return _height;
        }

        public void set_height(int _height) {
            this._height = _height;
        }

        public long get_wndid() {
            return _wndid;
        }

        public void set_wndid(long _wndid) {
            this._wndid = _wndid;
        }

        public int get_a() {
            return _a;
        }

        public void set_a(int _a) {
            this._a = _a;
        }

        public int get_r() {
            return _r;
        }

        public void set_r(int _r) {
            this._r = _r;
        }

        public int get_g() {
            return _g;
        }

        public void set_g(int _g) {
            this._g = _g;
        }

        public int get_b() {
            return _b;
        }

        public void set_b(int _b) {
            this._b = _b;
        }

        @Override
        public String toString() {
            return "Whiteboard{" +
                    "_boardId='" + _boardId + '\'' +
                    ", _ownId='" + _ownId + '\'' +
                    ", _ownName='" + _ownName + '\'' +
                    ", _title='" + _title + '\'' +
                    ", _description='" + _description + '\'' +
                    ", _remoteBgUrl='" + _remoteBgUrl + '\'' +
                    ", _width=" + _width +
                    ", _height=" + _height +
                    ", _wndid=" + _wndid +
                    ", _a=" + _a +
                    ", _r=" + _r +
                    ", _g=" + _g +
                    ", _b=" + _b +
                    '}';
        }
    }

    /**
     * 颜色定义（It is only called by native code.）
     */
    public class tagColor {
        public long color;

        public tagColor() {
            color = 0;
        }

        public tagColor(long val) {
            color = val;
        }

        public tagColor(char r, char g, char b, char a) {
            color = ((r | ((long) g << 8)) | (((long) b) << 16)) | (((long) a) << 24);
        }


        public long r() {
            return color & 0xFF;
        }

        public long g() {
            return (color >> 8) & 0xFF;
        }

        public long b() {
            return (color >> 16) & 0xFF;
        }

        public long a() {
            return (color >> 24) & 0xFF;
        }

        public long rgb() {
            return color & 0xFFFFFF;
        }

        public long argb() {
            return ((b() | (g() << 8)) | (r() << 16) | a() << 24);
        }

        public void setR(char r) {
            color = (color & 0xFFFFFF00) | ((long) r & 0xFF);
        }

        public void setG(char g) {
            color = (color & 0xFFFF00FF) | (((long) g & 0xFF) << 8);
        }

        public void setB(char b) {
            color = (color & 0xFF00FFFF) | (((long) b & 0xFF) << 16);
        }

        public void setA(char a) {
            color = (color & 0x00FFFFFF) | (((long) a & 0xFF) << 24);
        }

        public void set(char r, char g, char b, char a) {
            setA(a);
            setR(r);
            setG(g);
            setB(b);
        }

    }

    public static class DisplayDimension {
        /**
         * dp -> px
         */
        public static int dp2px(Context context, int dp) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
        }

        /**
         * sp -> px
         */
        public static int sp2px(Context context, int sp) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
        }

        /**
         * px -> dp
         */
        public static int px2dp(Context context, int px) {
//        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, context.getResources().getDisplayMetrics());
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (px / scale + 0.5f);
        }

        /**
         * px -> sp
         */
        public static int px2sp(Context context, int px) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, context.getResources().getDisplayMetrics());
        }
    }

}
