package cn.tee3.avd;

import android.os.Message;

import java.util.List;

/**
 * 直播主播接口类
 *
 * 直播主播接口定义了直播主播对象创建、直播发布和关闭操作。
 */
public class MainBroadcaster extends Livecast {
    private static final String TAG = "MainBroadcaster";

    /** 视频混频布局类型 */
    public static enum MixerVideoLayoutType {
        vl_auto_overlay,					/**< 自动布局-窗口中重叠视频 */
        vl_auto_segment,					/**< 自动布局-分割窗口排列视频 */
        vl_manual,							/**< 手动布局  */
    }

    /**
     * 直播主播回调接口类
     *
     * 直播主播回调接口定义了直播对象操作的异步返回，直播状态通知等。
     */
    public static interface Listener {
        /// 异步返回
        /** 开启直播操作异步返回
         *
         * @param[in] result 错误代码。
         * @sa publish
         */
        public void onPublishResult(int result);
    }

    private MainBroadcaster(String roomId) {
        super(roomId, true);
    }
    public static MainBroadcaster obtain(String roomId) {
        Tlog.i(TAG, "obtain, roomId:" + roomId);
        Livecast room =  Livecast.obtain(roomId);
        if (null == room) {
            try {
                room = new MainBroadcaster(roomId);
            }
            catch (Exception e) {
                return null;
            }
            synchronized (rooms) {
                rooms.add(room);
            }
            Tlog.v(TAG, "obtain, created");
        }
        return (MainBroadcaster)room;
    }

    /** 设置主播房间回调接口
     * @param[in] listener 回调接口指针。
     * @return 返回错误代码。
     * @see Listener
     */
    public int setListener2(Listener listener) {
        Tlog.i(TAG, "setListener2, nativeListener:" + nativeListener + ",listener:" + listener);
        this.listener4cb2 = listener;
        return nativemainbdsetListener2(this.nativeListener);
    }

    /** 开启直播
     *
     * @param[in] pushUrl 直播rtmp推流地址。
     * @param[in] *preview 本地预览render接口。
     *
     * @return 返回错误代码。
     * @sa onPublishResult
     */
    public int publish(String pushUrl, VideoRenderer preview) {
        Tlog.i(TAG, "publish, pushUrl:" + pushUrl +",preview:"+preview+"this="+this+",nativeobj="+this.nativeobj+",nativeListener="+this.nativeListener);
        if (0 == this.nativeListener) {
            setListener(null);
        }
        beginNetProber();
        int ret = nativepublish(pushUrl, preview.nativeRender());
        return ret;
    }
    /** 关闭直播
     *
     * @return 返回错误代码。
     */
    public int unpublish() {
        Tlog.i(TAG, "unpublish,this=" + this + ",nativeobj=" + this.nativeobj + ",nativeListener=" + this.nativeListener);
        if (null != _netProber) {
            NetworkProber.instance().unregisterReceiver(_netProber);
            _netProber = null;
        }
        int ret = nativeunpublish();
        this.listener4cb = null;
        Tlog.v(TAG, "unpublish, out:");
        return ret;
    }
    /** 房间中踢出用户
     *
     * @param[in] reason 踢出用户的理由代码。
     * @param[in] userId 被踢出用户Id。
     *
     * @note 被踢用户将会在onLeaveIndication中接收到回调，被踢用户直接调用 leave 离开房间即可。
     * @return 返回错误代码。
     * @sa onLeaveIndication
     */
    public int kickoutUser(int reason, String userId) {
        Tlog.i(TAG, "kickoutUser, reason:" + reason + ",userId:" + userId);
        int ret = nativekickoutUser(reason, userId);
        Tlog.i(TAG, "kickoutUser, out:");
        return ret;
    }

    // 布局相关接口（layout all）
    /** 获取房间中已发布视频列表
     * @return 返回视频列表。
     * @note 视频列表包含摄像头、虚拟导入视频、屏幕共享视频；
     */
    public List<VideoDevice> getPublishedVideos() {
        return nativegetPublishedVideos();
    };
    /** 设置直播视频参数
     *
     * @param[in] layout 各子视频在直播视频中的布局类型
     * @param[in] width  直播视频图像宽
     * @param[in] height 直播视频图像高
     * @return 返回错误代码。
     */
    public int setLiveVideoTypeaSize(MixerVideoLayoutType layout, int width, int height) {
        Tlog.i(TAG, "setLiveVideoTypeaSize, layout:" + layout+",width="+width+",height="+height);
        return nativesetLiveVideoTypeaSize(layout.ordinal(), width, height);
    }
    /** 设置直播视频合屏时采用的拉伸方式
     * @param[in] scale	各子视频合屏时采用的拉伸方式，参考ScaleType
     * @return 返回错误代码。
     */
    public int setLiveVideoScaleType(VideoRenderer.ScalingType scale) {
        Tlog.i(TAG, "setLiveVideoScaleType, scale:" + scale);
        return nativesetLiveVideoScaleType(scale.ordinal());
    }
    /** 设置直播视频背景图片
     * @param[in] background 直播背景图
     * @return 返回错误代码。
     */
    public int setLiveVideoBackgroud(String background) {
        Tlog.i(TAG, "setLiveVideoBackgroud, background:" + background);
        return nativesetLiveVideoBackgroud(background);
    }
    /** 清理掉所有的混屏视频，包括主视频；如果需要再次开启合屏，需要重新设置直播视频和Overlay视频。
     *
     * @return 返回错误代码。
     */
    public void   clearLiveSubVideos() {
        Tlog.i(TAG, "clearLiveSubVideos");
        nativeclearLiveSubVideos();
    }

    //自动布局(layout auto)：设置自动布局参数和主视频后，sdk自动来布局子视频组合成直播视频
    /** 切换直播视频的主视频（若主视频掉线，本地主播视频切为主视频）
     *
     * @param[in] deviceId 摄像头Id，唯一标示一路共享的摄像头视频。
     * @return 返回错误代码。
     * @note 直播视频的主视频在vl_auto_overlay模式下可以做切换，缺省为主播视频
     */
    public int setLiveMainVideo(String deviceId) {
        Tlog.i(TAG, "setLiveMainVideo, deviceId="+deviceId);
        return nativesetLiveMainVideo(deviceId);
    }
    /** 直播视频自动布局的布局参数设置
     *
     * @param[in] isTopdown  各子视频在直播视频上的排列顺序，true: 从上往下（左到右）排列； false: 从下往上（左到右）排列
     * @param[in] w			各子视频相对直播视频的宽度比例，取值0.0~1.0，内部取值为：width (直播视频）x W
     * @param[in] h			各子视频相对直播视频的高度比例，取值0.0~1.0，内部取值为：height(直播视频）x H
     * @param[in] x_begin    初始子视频在直播视频的左上角左边位置，即x坐标，取值0.0~1.0，内部取值为：width (直播视频）x x_begin
     * @param[in] y_begin    初始子视频在直播视频的左上角上边位置，即y坐标，取值0.0~1.0，内部取值为：height(直播视频）x y_begin
     * @return 返回错误代码。
     * @note 缺省设置为：vl_auto_overlay布局类型，从下往上排列; w=h=0.3f; x_begin=0.7f; y_begin=0.7f;
     */
    public int autoLayoutParams(boolean isTopdown, float w, float h, float x_begin, float y_begin) {
        Tlog.i(TAG, "autoLayoutParams, isTopdown="+isTopdown+",x_begin="+x_begin+",y_begin="+y_begin+",w="+w+",h="+h);
        return nativeautoLayoutParams(isTopdown, w, h, x_begin, y_begin);
    }

    //手动布局(layout manual)：完全手动布局整个直播视频，可以将一个个子视频排布在直播视频的任意位置
    /** 添加视频到直播视频特定位置
     *
     * @param[in] deviceId 摄像头Id，唯一标示一路共享的摄像头视频。
     * @param[in] zorder 多个视频覆盖时，前后位置，zorder越小，视频越在前面，后面会被覆盖；取值0-n
     * @param[in] x 此视频在直播视频的左上角左边位置，即x坐标，取值0.0~1.0，内部取值为：width (直播视频）x X
     * @param[in] y 此视频在直播视频的左上角上边位置，即y坐标，取值0.0~1.0，内部取值为：height(直播视频）x Y
     * @param[in] w 此视频在直播视频的宽度比例，取值0.0~1.0，内部取值为：width (直播视频）x W
     * @param[in] h 此视频在直播视频的高度比例，取值0.0~1.0，内部取值为：height(直播视频）x H
     * @return 返回错误代码。
     * @sa addMixerOverlayVideo
     */
    public int addLiveSubVideo(String deviceId, int zorder, float x, float y, float w, float h) {
        Tlog.i(TAG, "addLiveSubVideo, deviceId="+deviceId+",zorder="+zorder+",x="+x+",y="+y+",w="+w+",h="+h);
        return nativeaddLiveSubVideo(deviceId, zorder, x, y, w, h);
    }
    /** 更新附加视频在直播视频上显示的位置
     *
     * @param[in] deviceId 摄像头Id，唯一标示一路共享的摄像头视频。
     * @param[in] zorder 多个视频覆盖时，前后位置，zorder越小，视频越在前面，后面会被覆盖；取值0-n
     * @param[in] x 此视频在直播视频的左上角左边位置，即x坐标，取值0.0~1.0，内部取值为：width (直播视频）x X
     * @param[in] y 此视频在直播视频的左上角上边位置，即y坐标，取值0.0~1.0，内部取值为：height(直播视频）x Y
     * @param[in] w 此视频在直播视频的宽度比例，取值0.0~1.0，内部取值为：width (直播视频）x W
     * @param[in] h 此视频在直播视频的高度比例，取值0.0~1.0，内部取值为：height(直播视频）x H
     * @return 返回错误代码。
     */
    public int updateLiveSubVideo(String deviceId, int zorder, float x, float y, float w, float h) {
        Tlog.i(TAG, "updateLiveSubVideo, deviceId="+deviceId+",zorder="+zorder+",x="+x+",y="+y+",w="+w+",h="+h);
        return nativeupdateLiveSubVideo(deviceId, zorder, x, y, w, h);
    }
    /** 移除直播视频上的某一视频
     *
     * @param[in] deviceId 摄像头Id，唯一标示一路共享的摄像头视频。
     * @return 返回错误代码。
     */
    public void   removeLiveSubVideo(String deviceId) {
        Tlog.i(TAG, "removeLiveSubVideo, deviceId="+deviceId);
        nativeremoveLiveSubVideo(deviceId);
    };

    //
    @Override
    protected void dispose() {
        nativeviewersetListener2(0);
        listener4cb2 = null;
        super.dispose();
    }

    protected Listener listener4cb2 = null;
    @Override
    protected boolean initHandler() {
        super.initHandler();
        if (null != listenerHandler) {
            return true;
        }
        AVDEngine.runOnLoopThreadSync(new Runnable() {
            @Override
            public void run() {
                initHandler_main();
            }
        });
        return true;
    }
    private boolean initHandler_main() {
        this.listenerHandler = new BroadListenerHandler();
        return true;
    }
    protected class BroadListenerHandler extends ListenerHandler {
        public BroadListenerHandler() {
            super();
        }
        public void handleMessage(Message msg) {
            Tlog.v(TAG, "handleMessage, msg:"+msg.toString());
            if (null == listener4cb) {
                super.handleMessage(msg);
                return;
            }
            switch (msg.what) {
                case msg_onPublishResult:
                    listener4cb2.onPublishResult(msg.arg1);
                    break;
            }
            super.handleMessage(msg);
        }
    }

}
