/*
函数回调类型:
function callback(data){
}

观察者回调类型:
function observer(ignore,topic,data){
}

同步调用clientCommon.call 示例:
clientCommon.call(function(clientCommon,argv){
return clientCommon.getCityCode();
},[0,1,2],function(ret){
});
*/

var clientCommon = (function () {
    var CLIENTAPI_METHOD = 1;             //方法调用
    var CLIENTAPI_PROPERTYGET = 2;        //获取属性
    var CLIENTAPI_PROPERTYPUT = 4;        //设置属性
    var CLIENTAPI_PROPERTYPUTREF = 8;     //设置属性

    //判断是否是webkit客户端
    function isWebkit() {
        try {
            if (external.isWebkit) {
                return true;
            }
        } catch (e) { }
        return false;
    }

    //公共方法
    function initCommonFunc() {
        function apply(func, argv) {
            var ret;
            if (argv) {
                ret = func.apply(this, argv);
            } else {
                ret = func.apply(this);
            }
            return ret;
        }

        var obj = {
            //异步接口调用
            send: function (desc, type, name, param, callback, obj) {
                if (desc) {
                    if (external.send) {
                        external.send(desc, name, type, param, callback);
                    }
                } else {
                    if (obj.send) {
                        obj.__send(name, type, param, callback);
                    }
                }
            },

            //异步发送一段js函数代码到客户端中执行
            sendFunc: function () {
                var argc = arguments.length;

                if (argc == 1) {
                    return;
                }

                var func = arguments[0];
                var params = arguments[1] ? arguments[1] : null;
                var callback = arguments[2] ? arguments[2] : null;

                function eraseFuncName(code) {
                    var n = code.indexOf("(", 0);
                    var str = code.substr(n);
                    return "function" + str;
                }

                function replaceExternal(code) {
                    return code.replace(/external./g, "Components.");
                }

                function funcCall(code, params) {
                    function mergeArgus(params) {
                        function procString(str) {
                            return '"' + str + '"';
                        }

                        function procObject(obj) {
                            var ss = [];
                            for (var p in obj) {
                                ss.push(p + ':' + procElement(obj[p]));
                            }
                            return '{' + ss.join(',') + '}';
                        }

                        function procArray(a) {
                            var ss = [];
                            for (var i = 0; i < a.length; i++) {
                                ss.push(procElement(a[i]));
                            }
                            return '[' + ss.join(',') + ']';
                        }

                        function procElement(el) {
                            if (typeof (el) == "undefined") {
                                el = "undefined";
                            }
                            else if (typeof (el) == "string") {
                                el = procString(el);
                            }
                            else if (typeof (el) == "object") {
                                if (el) {
                                    if (el.length) {
                                        el = procArray(el);
                                    } else {
                                        el = procObject(el);
                                    }
                                } else {
                                    el = "null";
                                }
                            }
                            return el;
                        }

                        if (params) {
                            var len = params.length;
                            if (len != 0) {
                                var ss = [];
                                for (var i = 0; i < len; i++) {
                                    ss.push(procElement(params[i]));
                                }
                                return ss.join(',');
                            }
                        }

                        return '';
                    }

                    return '(' + code + ')(' + mergeArgus(params) + ');';
                }

                if (typeof (func) == "function") {
                    var code = func.toString();
                    code = eraseFuncName(code);
                    code = funcCall(code, params);
                    code = replaceExternal(code);

                    this.send('@pplive.com/ui/mainwindow;1', CLIENTAPI_METHOD, 'execScript', [code], callback);
                    //                  this.send('@pplive.com/ui/mainwindow;1', CLIENTAPI_METHOD, 'ExecuteCode', [code], callback);
                }
            },

            //IE与webkit支持,IE下直接执行,webkit下发送一段js代码到客户端执行,使用回调函数返回
            compatibleCall: function (syncFunc, argv, callback) {
                if (isWebkit()) {
                    this.sendFunc(syncFunc, argv, callback);
                } else {
                    var ret = apply(syncFunc, argv);
                    if (callback) {
                        callback(ret);
                    }
                }
            }
        };
        return obj;
    }

    //同步方法
    function initSyncFunc() {
        //获取收藏最近观看信息
        function getInfo(begin, len, type) {
            var list = [];
            var lBegin = begin;
            var lLen = len;
            var lCount = 0;
            try {
                var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                var watchlog = external.GetObject('@pplive.com/PPChLocalManager;1');
                var channels = null;
                if (type == 'favorite') {
                    channels = channelFactory.favLive;
                } else if (type == 'recent') {
                    channels = channelFactory.recent;
                } else {
                    return '{"tcount":0,"count":0,"list":[]}';
                }

                var lCount = channels.channelCount;

                if (lBegin < 0 || lLen < 0 || lBegin + lLen > lCount) {
                    lBegin = 0;
                    lLen = 0;
                }
                list.push('"tcount":' + lCount);
                list.push('"count":' + lLen);
                var array = [];

                for (i = lBegin; i < lBegin + lLen; i++) {
                    var line = [];
                    var channel = channels.channel(i);
                    var ID = channel.ID;
                    var isHJ = channel.hjType != 0;
                    var lastWatchID = isHJ ? watchlog.GetLastWatch(ID) : '';

                    line.push('"index":' + i);
                    line.push('"Name":"' + channel.Name.replace(/"/g, '\\"') + '"');
                    line.push('"ID":' + ID);
                    line.push('"CatalogID":' + channel.CatalogID);
                    var duration = channel.duration;
                    if (!duration) {
                        duration = watchlog.GetVideoDuration(isHJ ? lastWatchID : ID);
                    }
                    line.push('"duration":' + duration);
                    var pos = channel.pos;
                    if (!pos) {
                        pos = watchlog.GetWatchPos(isHJ ? lastWatchID : ID);
                    }
                    line.push('"pos":' + pos);
                    line.push('"vtp":' + channel.vtp);
                    line.push('"ft":' + channel.ft);
                    line.push('"mode":' + channel.mode);
                    line.push('"Collection":' + channel.Collection);
                    line.push('"hjType":' + channel.hjType);
                    line.push('"videoType":' + channel.videoType);
                    array.push('{' + line.join(',') + '}');
                }
                list.push('"list":[' + array.join(',') + ']');
            } catch (e) { }
            return '{' + list.join(',') + '}';
        }

        var obj = {
            //获取地区码
            getCityCode: function () {
                var code = 1;
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    code = channelFactory.Citycode;
                    if (!code) {
                        var channelManager = channelFactory.live();
                        code = channelManager.cityCode;
                    }
                } catch (e) { }
                return code;
            },

            //获取真实地区码
            getRealCityCode: function () {
                var code = 1;
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    code = channelFactory.RealCitycode;
                    if (!code) {
                        var channelManager = channelFactory.live();
                        code = channelManager.realCityCode;
                    }
                } catch (e) { }
                return code;
            },

            //获取用户类型
            getUserType: function () {
                var code = 0;
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    code = channelFactory.UserType;
                    if (!code) {
                        var channelManager = channelFactory.live();
                        code = channelManager.UserType;
                    }
                } catch (e) { }
                return code;
            },

            //获取客户端版本
            getClientVer: function () {
                var version = '0.0';
                try {
                    var ppframe = external.GetObject('@pplive.com/PPFrame;1');
                    version = ppframe.PPTVVersion;
                } catch (e) { }
                return version;
            },

            //用户是否登录
            userIsLogin: function () {
                try {
                    var passport = external.GetObject('@pplive.com/passport;1');
                    return passport.state == 0;
                } catch (e) { }
                return false;
            },
			
	        //用户登出
	        userLogout: function() {
	            try {
	                var passport = external.GetObject('@pplive.com/passport;1');
		            passport.Logout();
	            } catch (e) { }
	        },

            //获取用户信息
            getUserInfo: function () {
                try {
                    var passport = external.GetObject('@pplive.com/passport;1');
                    var o = null;
                    if (this.userIsLogin()) {
                        o = {
                            userName: passport.userName,
                            nickName: passport.nickName,
                            token: passport.token,
                            isVip: passport.IsVipUser,
                            encodeInfo: 'infovalue=' + passport.EncodeInfo.replace('index=', 'infoindex=') + '&isvip=' + (passport.IsVipUser ? 1 : 0)
                        };
                    }
                    return o;
                } catch (e) { }
                return null;
            },

            //获取登陆后跳转url
            makePassportRedirectUrl: function (url) {
                if (!this.userIsLogin()) {
                    return url;
                }

                var passport = external.GetObject('@pplive.com/passport;1');
                return 'http://passport.pptv.com/ClientLoginV2.do?infoValue=' + passport.EncodeInfo + '&returnURL=' + encodeURIComponent(url);
            },

            //获取服务器时间
            getServerTime: function () {
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    var channelManager = channelFactory.live();
                    return channelManager.ts;
                } catch (e) { }
                return null;
            },

            //设置剪贴板文字
            setClipboardText: function (txt) {
                try {
                    var ppFrame = external.GetObject('@pplive.com/PPFrame;1');
                    ppFrame.ClipboardText = txt;
                } catch (e) { }
            },

            //#region show client window
            //弹出登录窗口
            showLoginBox: function (txt, chid, aid) {
                if (txt) {
                    try {
                        var passport = external.GetObject('@pplive.com/passport;1');
                        passport.SetLoginReason(txt);
                    } catch (e) { }
                }
                try {
                    var uiMainWindow = external.GetObject('@pplive.com/ui/mainwindow;1');
                    uiMainWindow.showModalDialog('signin2.xml', { chid: chid, aid: aid });
                } catch (e) { }

                return this.userIsLogin();
            },

            //弹出注册窗口
            showRegBox: function (chid, aid) {
                try {
                    var ui = external.GetObject2('@pplive.com/ui/mainwindow;1');
                    ui.ShowRegUser(chid, aid);
                    return false;
                } catch (e) { }
                return false;
            },

            //弹出vip窗口
            showVipBox: function (chid, isVip, isVipStream, aid) {
                try {
                    var passport = external.GetObject('@pplive.com/passport;1');
                    if (!passport.IsVipUser && (isVip || isVipStream)) {
                        var uiMainWindow = external.GetObject('@pplive.com/ui/mainwindow;1');
                        uiMainWindow.CheckVipPlay(chid, isVip, isVipStream, aid);
                        return false;
                    }
                } catch (e) { }
                return true;
            },

            //弹出下载管理窗口
            showDownloadManagerBox: function () {
                try {
                    var uiMainWindow = external.GetObject('@pplive.com/ui/mainwindow;1');
                    uiMainWindow.showDownloadMgrWnd();
                } catch (e) { }
                try {
                    var PPLState = external.GetObject2('@pplive.com/PPLStat;1');
                    PPLState.PPTVClientButtonClick('managedownfile1');
                } catch (e) { }
            },

            //弹出下载窗口
            //	 var list = [
            //		{ chid: '', cid: '', title: '', hjChid: 0, hjTitle: '', disable: false, ft_all: 3 },
            //		{ chid: '', cid: '', title: '', hjChid: 0, hjTitle: '', disable: false, ft_all: 3 },
            //    ];
            showDownloadBox: function (vtp, list) {
                try {
                    var downloadMgr = external.GetObject('@pplive.com/chDownloadMgr;1');
                    for (var i = 0, len = list; i < len; i++) {
                        var item = list[i];
                        try {
                            downloadMgr.AddHjTask2(item.chid, item.cid, item.hjChid, vtp, item.title, item.hjTitle, disable ? 0 : 1, item.ft_all, -1, 0, 0);
                        } catch (e) {
                            downloadMgr.AddHjTask(item.chid, item.cid, item.hjChid, vtp, item.title, item.hjTitle);
                        }
                    }
                    downloadMgr.ShowCollectionDlg();
                } catch (e) { }
            },

            //弹出分享窗口
            showShareBox: function (chid, cid, isHj) {
                try {
                    var uiWindow = external.GetObject("@pplive.com/ui/mainwindow;1");
                    uiWindow.popSharewnd(chid, cid, isHj);
                } catch (e) { }
            },
            //#endregion

            //#region fav
            //获取收藏
            getFavList: function (begin, len) {
                return getInfo(begin, len, 'favorite');
            },

            //查找是否收藏
            findFav: function (isHj, chid) {
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    return channelFactory.favLive.findItemByID(isHj, chid) != null;
                } catch (e) { }
                return false;
            },

            //删除收藏
            delFav: function (isHj, chid) {
                try {
                    var chMgrFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    var fav = chMgrFactory.favLive;
                    fav.deleteChannelByID(isHj, chid);
                } catch (e) { }
            },

            //加入收藏
            addFav: function (isHj/*是否合集*/, cid/*分类id*/, chid/*频道id*/, chName/*频道名*/, isLive/*是否直播*/, isVip/*是否vip频道*/, vtp, deny_download, ft_all) {
                try {
                    var channelFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    try {
                        channelFactory.favLive.addChannelByIDEx(isHj, cid, chid, chName, isLive ? 0 : 3, isVip ? 1 : 0, 0/*1新 2推荐*/, vtp, '', 0, -1, 1, deny_download ? 1 : 0, 0, ft_all);
                    } catch (e) {
                        channelFactory.favLive.addChannelByID(isHj, cid, chid, chName, isLive ? 0 : 3, isVip ? 1 : 0, 0/*1新 2推荐*/);
                    }
                } catch (e) { }
            },

			//删除所有收藏
	        clearFav:function() {
		        try {
		           var chMgrFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
		           var favLive = chMgrFactory.favLive;
		           favLive.deleteAll();
		        } catch (e) { }
	        },
            //#endregion

            //#region hsy
            //获取最近观看
            getHsyList: function (begin, len) {
                return getInfo(begin, len, 'recent');
            },

            //删除最近观看
            delHsy: function (isHj, chid) {
                try {
                    var chMgrFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
                    var recent = chMgrFactory.recent;
                    recent.deleteChannelByID(isHj, chid);
                } catch (e) { }
            },

	        //删除所有最近观看
	        clearHsy:function() {
		        try {
		           var chMgrFactory = external.GetObject('@pplive.com/ChannelManagerFactory;1');
		           var recent = chMgrFactory.recent;
		           recent.deleteAll();
		        } catch (e) { }
	        },

            getLastWatchChid: function (chid) {
                try {
                    var watchlog = external.GetObject('@pplive.com/PPChLocalManager;1');
                    return watchlog.GetLastWatch(chid);
                } catch (e) { }
                return null;
            },

            isWatched: function (chid) {
                try {
                    var watchlog = external.GetObject('@pplive.com/PPChLocalManager;1');
                    return watchlog.Find(chid) == 1;
                } catch (e) { }
                return false;
            },

            getCurrPlayChid: function () {
                try {
                    var ppp = external.GetObject('PPP');
                    return ppp.channelId;
                } catch (e) { }
                return null;
            },
            //#endregion

            //#region play
            //播放 url:播放串 ly:来源 minBox:是否小窗(不支持小窗则正常模式播放)
			playByLink: function (url, ly, minBox, referer) {
                try {
                    var ppframe = external.GetObject('PPFrame');
                    ppframe.CreatePlayer();
                } catch (e) { }

                try {
                    var ppp = external.GetObject('PPP');
                    ppp.playList.clearAll();
                    ppp.playList.addUrl(url);
                    if (minBox) {
                        try {
                            ppp.PlayList.holder = 1;
                        } catch (e) { }
                    }
					if (referer){
						try{
							ppp.playList.Referer = referer;
						} catch (e) { }
					}
                    ppp.startPlayList(ly, 0);
                } catch (e) { }
            }
            //#endregion
        };
        return obj;
    }

    //observer 方法
    function initObserver() {
        var observerObject = {};

        function getName() {
            return window.location.href;
        }

        var obj = {
            //添加事件
            addObserver: function (topic, callback) {
                var obj = external.GetObject("@pplive.com/observer-service;1");
                obj.addObserver(topic, callback);
            },
            //取消事件
            removeObserver: function (topic, callback) {
                var obj = external.GetObject("@pplive.com/observer-service;1");
                obj.removeObserver(topic, callback);
            },
            //通知事件
            notifyObservers: function (ignore, topic, data) {
                var obj = external.GetObject("@pplive.com/observer-service;1");
                obj.notifyObservers(ignore, topic, data);
            },
            //添加一个事件监听，兼容ie和webkit
            addObserverListener: function (topics, vec, callback) {
                try {
                    if (isWebkit()) {
                        for (var i = 0; i < topics.length; i++) {
                            this.addObserver(topics[i], function (ignore, topic, data) {
                                callback(data);
                            });
                        }
                    } else {
                        var uiMainWindow = external.GetObject('@pplive.com/ui/mainwindow;1');
                        if (!observerObject[vec]) {
                            observerObject[vec] = [];
                            uiMainWindow[vec][getName()] = function (data) {
                                for (var keyname in observerObject[vec]) {
                                    try {
                                        observerObject[vec][keyname](data);
                                    }
                                    catch (e) { }
                                }
                            };
                        }
                        observerObject[vec].push(callback);
                    }
                } catch (e) { }
            }
        };
        return obj;
    }

    //客户端JS异步API
    function initClientApi() {
        var sync = initSyncFunc();
        var c = initCommonFunc();
        var observer = initObserver();

        var clientApi = {
            isWebkit: function () { return isWebkit(); },
            getCityCode: function () { return sync.getCityCode(); },
            getRealCityCode: function () { return sync.getRealCityCode(); },
            getUserType: function () { return sync.getUserType(); },
            getClientVer: function () { return sync.getClientVer(); },
            userIsLogin: function () { return sync.userIsLogin(); },
            userLogout: function() { c.compatibleCall(sync.userLogout, []); },
            getUserInfo: function () { return sync.getUserInfo(); },
            makePassportRedirectUrl: function (url) { return sync.makePassportRedirectUrl(url); },
            getServerTime: function () { return sync.getServerTime(); },
            setClipboardText: function (txt) { c.compatibleCall(sync.setClipboardText, [txt]); },
            findFav: function (isHj, chid) { return sync.findFav(isHj, chid); },
            clearHsy: function() { c.compatibleCall(sync.clearHsy, []); },
            clearFav: function() { c.compatibleCall(sync.clearFav, []); },
            getLastWatchChid: function (chid) { return sync.getLastWatchChid(chid); },
            isWatched: function (chid) { return sync.isWatched(chid); },
            getCurrPlayChid: function () { return sync.getCurrPlayChid(); },
            call: function (func, args, callback) {
                if (!args) {
                    args = [];
                }
                c.compatibleCall(function (func, args, initSyncFunc) {
                    return func.apply(null, [initSyncFunc()].concat(args));
                }, [func, args, initSyncFunc], callback);
            },

            //#region show client window
            //登录窗口
            showLoginBox: function (callback, txt, chid, aid) {
                c.compatibleCall(sync.showLoginBox, [txt, chid, aid], callback);
            },
            //注册窗口
            showRegBox: function (callback, chid, aid) {
                c.compatibleCall(sync.showRegBox, [chid, aid], callback);
            },
            //vip窗口
            showVipBox: function (callback, chid, isVip, isVipStream, aid) {
                c.compatibleCall(sync.showVipBox, [chid, isVip, isVipStream, aid], callback);
            },
            //下载管理对话框
            showDownloadManagerBox: function (callback) {
                c.compatibleCall(sync.showDownloadManagerBox, [], callback);
            },
            //下载窗口
            showDownloadBox: function (callback, vtp, list) {
                c.compatibleCall(sync.showDownloadBox, [vtp, list], callback);
            },
            //分享窗口
            showShareBox: function (callback, chid, cid, isHj) {
                c.compatibleCall(sync.showShareBox, [chid, cid, isHj], callback);
            },
            //#endregion

            //#region file
            writeFile: function (key, value) {
                if (localStorage) {
                    localStorage.setItem(key, value);
                } else {
                    try {
                        var serializer = null;
                        try {
                            var EWA = external.GetObject('EWA');
                            serializer = EWA.CreateSerializer();
                            serializer.Open(key);
                        } catch (e) {
                            var ppFrame = external.GetObject("@pplive.com/PPFrame;1");
                            serializer = ppFrame.CreateComponent(1);
                            serializer.Open(key);
                        }
                        serializer.Write(value);
                        serializer.Close();
                    } catch (e) { }
                }
            },
            readFile: function (key) {
                if (localStorage) {
                    return localStorage.getItem(key);
                } else {
                    try {
                        var serializer = null;
                        try {
                            var EWA = external.GetObject('EWA');
                            serializer = EWA.CreateSerializer();
                            serializer.Open(key);
                        } catch (e) {
                            var ppFrame = external.GetObject("@pplive.com/PPFrame;1");
                            serializer = ppFrame.CreateComponent(1);
                            serializer.Open(key);
                        }
                        var txt = serializer.Read(-1);
                        serializer.Close();
                        return txt;
                    } catch (e) { }
                    return '';
                }
            },
            //#endregion

            //#region fav
            //获取收藏
            getFavList: function (callback, begin, len) {
                if (isWebkit()) {
                    function GetFavorite(begin, len) {
                        var channelManagerFactory = external.GetObject("@pplive.com/ChannelManagerFactory;1");
                        return channelManagerFactory.GetFavorite(begin, len);
                    }
                    c.compatibleCall(GetFavorite, [begin, len], function (data) {
                        callback(eval('(' + data + ')'));
                    });
                } else {
                    callback(eval('(' + sync.getFavList(begin, len) + ')'));
                }
            },
            //加入收藏
            addFav: function (callback, isHj, cid, chid, chName, isLive, isVip, vtp, deny_download, ft_all) {
                c.compatibleCall(sync.addFav, [isHj, cid, chid, chName, isLive, isVip, vtp, deny_download, ft_all], callback);
            },
            //删除收藏
            delFav: function (isHj, chid) {
                c.compatibleCall(sync.delFav, [isHj, chid]);
            },

            //#region hsy
            //获取最近观看
            getHsyList: function (callback, begin, len) {
                if (isWebkit()) {
                    function GetRecent(begin, len) {
                        var channelManagerFactory = external.GetObject("@pplive.com/ChannelManagerFactory;1");
                        return channelManagerFactory.GetRecent(begin, len);
                    }
                    c.compatibleCall(GetRecent, [begin, len], function (data) {
                        callback(eval('(' + data + ')'));
                    });
                } else {
                    callback(eval('(' + sync.getHsyList(begin, len) + ')'));
                }
            },

            //删除最近观看
            delHsy: function (isHj, chid) {
                c.compatibleCall(sync.delHsy, [isHj, chid]);
            },
            //endregion

            //#region play
            //播放 url:播放串 ly:来源 minBox:是否小窗(不支持小窗则正常模式播放)
            playByLink: function (url, ly, minBox) {
				var referer = window.location.href;
                c.compatibleCall(sync.playByLink, [url, ly, minBox, referer]);
            },
            //#endregion

            //#region event notify
            onLogin: function (callback) {
                observer.addObserverListener(["login"], "vecOnUserLogin", callback);
            },
            onLoginout: function (callback) {
                observer.addObserverListener(["logout"], "vecOnUserLogin", callback);
            },
	        onLogout: function (callback) {
                observer.addObserverListener(["logout"], "vecOnUserLogin", callback);
            },
            onPlayStateChange: function (callback) {
                observer.addObserverListener(["player-statechange"], "vecOnPlayStateChange", callback);
            },
            onCityCodeChange: function (callback) {
                observer.addObserverListener(["citycodechanged"], "vecOnCityCodeChange", callback);
            },
            onHsyListChange: function (callback) {
                observer.addObserverListener(["recentchanged"], "vecFavoriteEvent", callback);
            },
            onFavListChange: function (callback) {
                observer.addObserverListener(["favoritechanged"], "vecFavoriteEvent", callback);
            }
            //#endregion
        };
        return clientApi;
    }
    return initClientApi();
})();



