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

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import java.util.LinkedList;

/**
 * 注释模块.
 */

public class MAnnotationInternal {
    private static final String TAG = "MAnnotationInternal";
    private long nativeobj;

    ////注释类型
//    public static final long annotation_tool_mouse = 1 << 0;
//    public static final long annotation_tool_line = 1 << 1;
//    public static final long annotation_tool_rectangle = 1 << 2;
//    public static final long annotation_tool_ellipse = 1 << 3;
//    public static final long annotation_tool_polyline = 1 << 4;
//    public static final long annotation_tool_polygon = 1 << 5;
//    public static final long annotation_tool_hlight_point = 1 << 6;
//    public static final long annotation_tool_hlight_texttag = 1 << 7;
//    public static final long annotation_tool_eraser_line = 1 << 8;
//    public static final long annotation_tool_eraser_rectangle = 1 << 9;
//    public static final long annotation_tool_rhomb = 1 << 10;
//    public static final long annotation_tool_arrow = 1 << 11;
//    public static final long annotation_tool_success = 1 << 12;
//    public static final long annotation_tool_failure = 1 << 13;


    public MAnnotationInternal(long annoObj) {
        Tlog.d(TAG, "new MAnnotationInternal, obj=" + this.nativeobj);
        nativeobj = annoObj;
    }

    public static boolean isSupported(long type) {
        Tlog.d(TAG, "MAnnotationInternal, isSupported ");
        return nativeisSupported(type);
    }

    /**
     * 移除指定注释
     * @param boardId 白板id
     * @param annotationId 注释id
     * @return 成功:0
     */
    public int removeAnnotationObj(String boardId, String annotationId) {
        Tlog.d(TAG, "MAnnotationInternal, removeAnnotationObj ");
        return nativeremoveAnnotationObj(boardId, annotationId);
    }

    /**
     * 撤销绘制
     * @param boardId 白板id
     * @return 成功:0
     */
    public int undo(String boardId) {
        Tlog.d(TAG, "MAnnotationInternal, undo ");
        return nativeundo(boardId);
    }

    /**
     * 重新绘制
     * @param boardId 白板id
     * @return 成功:0
     */
    public int redo(String boardId) {
        Tlog.d(TAG, "MAnnotationInternal, redo ");
        return nativeredo(boardId);
    }

    /**
     * 清空白板
     * @param boardId 白板id
     * @return 成功:0
     */
    public int clearAnnotations(String boardId) {
        Tlog.d(TAG, "MAnnotationInternal, clearAnnotations ");
        return nativeclear(boardId);
    }

    /**
     * 添加注释
     * @param boardId 白板id
     * @param annotationStr 注释主体
     * @return 成功:0
     */
    public int addAnnotationObj(String boardId, String annotationStr) {
        Tlog.d(TAG, "MAnnotationInternal, addAnnotationObj ");
        return nativeaddAnnotationStr(boardId, annotationStr);
    }

    /**
     * 更新指定注释
     * @param annotationId 注释id
     * @param annotationStr 注释主体
     * @return 成功:0
     */
    public int updateAnnotationObj(String annotationId, String annotationStr) {
        Tlog.d(TAG, "MAnnotationInternal, updateAnnotationObj ");
        return nativeupdateAnnotationStr(annotationId, annotationStr);
    }

    /**
     * 获取白板注释列表
     * @param boardId 白板id
     * @return 成功:0
     */
    public LinkedList<String> getAnnotationList(String boardId) {
        Tlog.d(TAG, "MAnnotationInternal, updateAnnotationObj ");
        return nativegetAnnotationList(boardId);
    }

    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 freeListener() {
        if (null != listener4cb) {
            nativeFreeListener(nativeListener);
            Tlog.d(TAG, "freeListener, Free nativelistener:" + nativeListener);
        }
    }

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

    /**
     * 注释接口
     */
    public interface Listener {
        void onAnnotationDelNotify(String j_boardId, String annotation_id);

        void onAnnotationAddNotifyStr(String j_boardId, String j_annotationstr);

        void onAnnotationUpdateNotifyStr(String j_boardId, String j_annotationstr);

        void onAnnotationClearNotify(String j_boardId, String j_userId);
    }

    private static native boolean nativeisSupported(long type);

    private native long nativeCreateListener(Listener listener);

    private native void nativeFreeListener(long nativeListener);

    private native int nativeremoveAnnotationObj(String j_boardId, String j_annotationId);

    private native int nativeaddAnnotationStr(String j_boardId, String j_annotationstr);

    private native int nativeundo(String boardId);

    private native int nativeredo(String boardId);

    private native int nativeclear(String boardId);

    private native int nativeupdateAnnotationStr(String j_annotationId, String j_annotationstr);

    private native LinkedList<String> nativegetAnnotationList(String j_annotationId);

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


    private static final int msg_onAnnotationDelNotifiy = 1;
    private static final int msg_onAnnotationAddNotifiy = 2;
    private static final int msg_onAnnotationUpdateNotifiy = 3;
    private static final int msg_onAnnotationClearNotfiy = 4;

    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() {
            public void handleMessage(Message msg) {
                Tlog.v(TAG, "handleMessage, msg:" + msg.toString());
                if (null == listener4cb) {
                    super.handleMessage(msg);
                    return;
                }
                switch (msg.what) {
                    case msg_onAnnotationDelNotifiy:
                        listener4cb.onAnnotationDelNotify(msg.getData().getString("j_boardId"), msg.getData().getString("annotationStr"));
                        break;
                    case msg_onAnnotationAddNotifiy:
                        listener4cb.onAnnotationAddNotifyStr(msg.getData().getString("j_boardId"), msg.getData().getString("annotationStr"));
                        break;
                    case msg_onAnnotationUpdateNotifiy:
                        listener4cb.onAnnotationUpdateNotifyStr(msg.getData().getString("j_boardId"), msg.getData().getString("annotationStr"));
                        break;
                    case msg_onAnnotationClearNotfiy:
                        listener4cb.onAnnotationClearNotify(msg.getData().getString("j_boardId"), msg.getData().getString("j_userId"));
                        break;

                }
                super.handleMessage(msg);
            }
        };
        return true;
    }

    private class SDKListener implements Listener {
        public SDKListener() {
        }

        @Override
        public void onAnnotationDelNotify(String j_boardId, String annotation_id) {
            if (null == listenerHandler) {
                return;
            }
            Message msg = obtainMessage(msg_onAnnotationDelNotifiy, j_boardId, annotation_id);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onAnnotationAddNotifyStr(String j_boardId, String j_annotationstr) {
            if (null == listenerHandler) {
                return;
            }
            Message msg = obtainMessage(msg_onAnnotationAddNotifiy, j_boardId, j_annotationstr);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onAnnotationUpdateNotifyStr(String j_boardId, String j_annotationstr) {
            if (null == listenerHandler) {
                return;
            }
            Message msg = obtainMessage(msg_onAnnotationUpdateNotifiy, j_boardId, j_annotationstr);
            listenerHandler.sendMessage(msg);
        }

        @Override
        public void onAnnotationClearNotify(String j_boardId, String j_userId) {
            if (null == listenerHandler) {
                return;
            }
            Message msg = obtainMessage(msg_onAnnotationClearNotfiy, j_boardId, j_userId);
            listenerHandler.sendMessage(msg);
        }
    }

    private Message obtainMessage(int what, String j_boardId, String annotationStr) {
        Message msg = Message.obtain(listenerHandler);
        msg.what = what;
        Bundle data = new Bundle();
        data.putString("j_boardId", j_boardId);
        data.putString("annotationStr", annotationStr);
        msg.setData(data);
        return msg;
    }

    /**
     * 注释主体
     */
    public static class AnnotationStr {
        public Annotationbase annotationbase;
        public MPoint[] points;

        public AnnotationStr(Annotationbase annotationbase, MPoint[] points) {
            this.annotationbase = annotationbase;
            this.points = points;
        }

        public Annotationbase getAnnotationbase() {
            return annotationbase;
        }

        public void setAnnotationbase(Annotationbase annotationbase) {
            this.annotationbase = annotationbase;
        }

        public MPoint[] getPoints() {
            return points;
        }

        public void setPoints(MPoint[] points) {
            this.points = points;
        }

        public static class Annotationbase {
            String annotation_id_;
            String user_id_;
            int line_width_;
            int line_arrow_;    // 1->代表曲线和直线，4->单箭头，6->双箭头
            String object_id_;
            int tool_type_;     //
            Rect annotation_rect_;
            Rect display_rect_;
            Rect object_rect_;
            MColor fill_color_; // 圆和矩形的填充颜色
            MColor line_color_;

            public Annotationbase(int tool_type_) {
                this.tool_type_ = tool_type_;
            }

            public Annotationbase(String annotation_id_, String user_id_, int line_width_, int line_arrow_, String object_id_, int tool_type_, Rect annotation_rect_, Rect display_rect_, Rect object_rect_, MColor fill_color_, MColor line_color_) {
                this.annotation_id_ = annotation_id_;
                this.user_id_ = user_id_;
                this.line_width_ = line_width_;
                this.line_arrow_ = line_arrow_;
                this.object_id_ = object_id_;
                this.tool_type_ = tool_type_;
                this.annotation_rect_ = annotation_rect_;
                this.display_rect_ = display_rect_;
                this.object_rect_ = object_rect_;
                this.fill_color_ = fill_color_;
                this.line_color_ = line_color_;
            }

            public String getAnnotation_id_() {
                return annotation_id_;
            }

            public void setAnnotation_id_(String annotation_id_) {
                this.annotation_id_ = annotation_id_;
            }

            public String getUser_id_() {
                return user_id_;
            }

            public void setUser_id_(String user_id_) {
                this.user_id_ = user_id_;
            }

            public int getLine_width_() {
                return line_width_;
            }

            public void setLine_width_(int line_width_) {
                this.line_width_ = line_width_;
            }

            public int getLine_arrow_() {
                return line_arrow_;
            }

            public void setLine_arrow_(int line_arrow_) {
                this.line_arrow_ = line_arrow_;
            }

            public String getObject_id_() {
                return object_id_;
            }

            public void setObject_id_(String object_id_) {
                this.object_id_ = object_id_;
            }

            public int getTool_type_() {
                return tool_type_;
            }

            public void setTool_type_(int tool_type_) {
                this.tool_type_ = tool_type_;
            }

            public Rect getAnnotation_rect_() {
                return annotation_rect_;
            }

            public void setAnnotation_rect_(Rect annotation_rect_) {
                this.annotation_rect_ = annotation_rect_;
            }

            public Rect getDisplay_rect_() {
                return display_rect_;
            }

            public void setDisplay_rect_(Rect display_rect_) {
                this.display_rect_ = display_rect_;
            }

            public Rect getObject_rect_() {
                return object_rect_;
            }

            public void setObject_rect_(Rect object_rect_) {
                this.object_rect_ = object_rect_;
            }

            public MColor getFill_color_() {
                return fill_color_;
            }

            public void setFill_color_(MColor fill_color_) {
                this.fill_color_ = fill_color_;
            }

            public MColor getLine_color_() {
                return line_color_;
            }

            public void setLine_color_(MColor line_color_) {
                this.line_color_ = line_color_;
            }

            public static class Rect {
                int bottom;
                int left;
                int right;
                int top;

                public Rect(int bottom, int left, int right, int top) {
                    this.bottom = bottom;
                    this.left = left;
                    this.right = right;
                    this.top = top;
                }

                public int getBottom() {
                    return bottom;
                }

                public void setBottom(int bottom) {
                    this.bottom = bottom;
                }

                public int getLeft() {
                    return left;
                }

                public void setLeft(int left) {
                    this.left = left;
                }

                public int getRight() {
                    return right;
                }

                public void setRight(int right) {
                    this.right = right;
                }

                public int getTop() {
                    return top;
                }

                public void setTop(int top) {
                    this.top = top;
                }
            }

            public static class MColor {
                int a;
                int r;
                int g;
                int b;

                public MColor(int a, int r, int g, int b) {
                    this.a = a;
                    this.r = r;
                    this.g = g;
                    this.b = b;
                }

                public int getA() {
                    return a;
                }

                public void setA(int a) {
                    this.a = a;
                }

                public int getR() {
                    return r;
                }

                public void setR(int r) {
                    this.r = r;
                }

                public int getB() {
                    return b;
                }

                public void setB(int b) {
                    this.b = b;
                }

                public int getG() {
                    return g;
                }

                public void setG(int g) {
                    this.g = g;
                }
            }
        }

        public static class MPoint {
            int x;
            int y;

            public MPoint() {
            }

            public MPoint(int x, int y) {
                this.x = x;
                this.y = y;
            }

            public int getX() {
                return x;
            }

            public void setX(int x) {
                this.x = x;
            }

            public int getY() {
                return y;
            }

            public void setY(int y) {
                this.y = y;
            }

            @Override
            public String toString() {
                return "MPoint{" +
                        "x=" + x +
                        ", y=" + y +
                        '}';
            }
        }
    }
}
