/**
 * Virtual USB PVR module
 */

(function () {

    if (typeof (pvrManager) === "undefined") {
        _debug('pvrManager not found');
        return;
    }

    var allow_local_recording = stb.user['allowed_stb_types_for_local_recording'].some(function (element) {
        return stb.type.toLowerCase().indexOf(element) != -1;
    });

    _debug('allow_local_recording', allow_local_recording);

    if (!allow_local_recording) {
        _debug('local pvr not allowed for ' + stb.type);
        return;
    }

    function PvrLocal() {

        //this.deferred_epg_records = [];

        this.error_codes = {
            "-1": get_word('pvr_error_wrong_param'),
            "-2": get_word('pvr_error_memory'),
            "-3": get_word('pvr_error_duration'),
            "-4": get_word('pvr_error_not_found'),
            "-5": get_word('pvr_error_wrong_filename'),
            "-6": get_word('pvr_error_record_exist'),
            "-7": get_word('pvr_error_url_open_error'),
            "-8": get_word('pvr_error_file_open_error'),
            "-9": get_word('pvr_error_rec_limit'),
            "-10": get_word('pvr_error_end_of_stream'),
            "-11": get_word('pvr_error_file_write_error')
        };

        this.duration_input = new DurationInputBox({ "max_val": 180 });

        this.stop_confirm = new ModalForm({
            "title": get_word('confirm_form_title'),
            "text": get_word('remote_pvr_stop_confirm')
        });
        this.stop_confirm.getTextDomObj().style.textAlign = "center";
        this.stop_confirm.enableOnExitClose();

        var scope = this;

        this.stop_confirm.addItem(new ModalFormButton(
            {
                "value": get_word("cancel_btn"),
                "onclick": function () {
                    scope.stop_confirm.hide();
                }
            }
        ));

        this.stop_confirm.addItem(new ModalFormButton(
            {
                "value": get_word("yes_btn"),
                "onclick": function () {
                    scope.stop_confirm.hide();
                    scope.stop_rec.call(scope, scope.stop_confirm.rec_id);
                }
            }
        ));

        this.rec_switch = function (ch) {
            _debug('pvr_local.rec_switch', ch);

            if (stb.player.prev_layer.on) {
                return;
            }

            var idx = stb.recordings.getIdxByVal('ch_id', ch.id);

            _debug('idx', idx);
            _debug('stb.recordings[idx]', stb.recordings[idx]);

            if (idx !== null && stb.recordings[idx].local == 1) {

                var now = new Date().getTime() / 1000;

                if ((now - stb.recordings[idx].t_start_ts) < 120) {

                    if (this.duration_input.on) {
                        this.duration_input.hide();
                    } else {

                        var self = this;
                        var rec_id = stb.recordings[idx].id;

                        this.duration_input.callback = function (duration) {
                            _debug('callback duration', duration);

                            var t_stop_ts = parseInt(stb.recordings[idx].t_start_ts, 10) + duration * 60;

                            var result = pvrManager.ChangeEndTime(stb.recordings[idx].internal_id, t_stop_ts);

                            if (self.is_error(result)) {
                                return;
                            }

                            stb.recordings[idx].t_stop_ts = t_stop_ts;

                            window.clearTimeout(stb.recordings[idx].del_timeout);

                            var del_timeout = (stb.recordings[idx].t_stop_ts - stb.recordings[idx].t_start_ts) * 1000;

                            _debug('del_timeout', del_timeout);

                            stb.recordings[idx].del_timeout = window.setTimeout(function () {
                                _debug('delete rec');
                                self.send_stop_rec(rec_id, true);
                            }, del_timeout);

                            stb.load(
                                {
                                    "type": "remote_pvr",
                                    "action": "update_record_on_stb_end_time",
                                    "rec_id": stb.recordings[idx].id,
                                    "stop_ts": stb.recordings[idx].t_stop_ts
                                },
                                function (result) {
                                    _debug('update_record_on_stb_end_time', result);
                                },
                                self
                            );
                        };

                        this.duration_input.show();
                    }
                }
            }
        };

        this.create_for_program = function (program, path, callback) {
            _debug('pvr_local.create_for_program', program, path);

            var ch_idx = stb.player.channels.getIdxByVal("id", program.ch_id);

            if (ch_idx === null) {
                stb.notice.show(get_word('Channel not found'));
                return;
            }

            this.create(stb.player.channels[ch_idx], path, program.start_timestamp, program.stop_timestamp, program, callback);
        };

        this.create = function (channel, path, start, end, program, callback) {
            _debug('pvr_local.create', channel, path);

            var self = this;

            this._get_link_for_channel(
                channel,

                function (url) {
                    channel.url = url;
                    self.start(channel, path, start, end, program, callback);
                }
            )
        };

        this._get_link_for_channel = function (channel, callback) {
            _debug('pvr_local._get_link_for_channel', channel);

            if (parseInt(channel.use_http_tmp_link) == 1 || parseInt(channel.use_load_balancing) == 1 || stb.user['force_ch_link_check']) {

                stb.load(
                    {
                        "type": "itv",
                        "action": "create_link",
                        "cmd": channel.cmd,
                        "for_pvr": 1
                    },
                    function (result) {

                        _debug('on pvr_local.create_link', result);

                        if (result.error == 'limit') {
                            stb.notice.show(word['player_limit_notice']);
                        } else if (result.error == 'nothing_to_play') {
                            stb.notice.show(word['player_file_missing']);
                        } else if (result.error == 'link_fault') {
                            stb.notice.show(word['player_server_error']);
                        } else {
                            callback && callback(this.get_clear_url(result.cmd));
                        }
                    },
                    this
                );

            } else {
                callback && callback(this.get_clear_url(channel.cmd));
            }
        };

        this.start = function (channel, path, start, end, program, callback) {
            _debug('pvr_local.start', channel, path, start, end);

            var url = channel.url;

            if (parseInt(channel.use_http_tmp_link) != 1 && parseInt(channel.use_load_balancing) != 1 && !stb.user['force_ch_link_check']
                && (!url || url.indexOf('http://') == -1 && url.indexOf('rtp://') == -1 && url.indexOf('udp://') == -1)) {

                stb.notice.show(get_word('rec_not_supported_format'));
                //return false;
                callback(false);
            }

            var now = Math.ceil(new Date().getTime() / 1000);

            start = start || now;
            end = end || now + 3 * 3600;

            if (!program) {
                var rec_id = pvrManager.CreateTask(url, path, start, end);
                _debug('rec_id', rec_id);

                if (this.is_error(rec_id)) {
                    callback(false);
                }
            }

            if (program && program.id != 0) {
                cur_prog = program.name
            } else {
                var epg = stb.epg_loader.get_curr_and_next(channel.id, start);

                if (epg && epg.length > 0) {
                    var cur_prog = epg[0].name || '';
                } else {
                    cur_prog = '';
                }
            }

            var record = {
                "id": 0,
                "real_id": 0,
                "ch_id": channel.id,
                "local": 1,
                "t_start_ts": start,
                "t_stop_ts": end,
                "program": cur_prog,
                "internal_id": rec_id,
                "file": path
            };

            var self = this;
            record['del_timeout'] = window.setTimeout(function () {
                _debug('delete rec');
                //self.remove_record_from_list(record.id, true);
                self.send_stop_rec(record.id, true);
            }, record['t_stop_ts'] * 1000 - new Date().getTime());

            /*stb.recordings.push(record);*/
            /* stb.player.show_rec_icon(record);*/

            stb.load(
                {
                    "type": "remote_pvr",
                    "action": program ? "start_deferred_record_on_stb" : "start_record_on_stb",
                    "ch_id": channel.id,
                    "file": path,
                    "start_ts": start,
                    "stop_ts": end,
                    "internal_id": rec_id ? rec_id : 0,
                    "deferred": !!start,
                    "program_id": program ? program.id : 0,
                    "program_real_id": program && program.real_id ? program.real_id : ''
                },
                function (result) {
                    _debug('on start_record_on_stb', result);

                    var real_id = result || 0;

                    _debug('real_id', real_id);

                    callback && callback(real_id);

                    /*var idx = stb.recordings.getIdxByVal('internal_id', rec_id);

                    stb.recordings[idx].id = stb.recordings[idx].real_id = real_id;*/

                    record.id = record.real_id = real_id;

                    var rm_idx = stb.recordings.getIdxByVal('id', real_id);

                    if (rm_idx !== null) {
                        stb.recordings.splice(rm_idx, 1);
                    }

                    stb.recordings.push(record);

                    var self = this;

                    if (program) {
                        record['start_timeout'] = window.setTimeout(function () {
                            _debug('start rec');

                            self._get_link_for_channel(
                                channel,
                                function (url) {

                                    var idx = stb.recordings.getIdxByVal('id', real_id);

                                    _debug('idx', idx);

                                    if (idx === null) {
                                        return;
                                    }

                                    stb.recordings[idx].internal_id = pvrManager.CreateTask(url, path, start, end);

                                    if (self.is_error(stb.recordings[idx].internal_id)) {
                                        self.remove_record_from_list(real_id);
                                        return;
                                    }

                                    if (stb.recordings[idx].ch_id == stb.player.cur_tv_item.id) {
                                        stb.player.show_rec_icon(stb.recordings[idx]);
                                    }

                                    stb.load(
                                        {
                                            "type": "remote_pvr",
                                            "action": "set_internal_id",
                                            "rec_id": real_id,
                                            "internal_id": stb.recordings[idx].internal_id
                                        },
                                        function (result) {
                                            _debug('on set_internal_id', result);
                                        }
                                    )
                                }
                            );

                        }, record['t_start_ts'] * 1000 - new Date().getTime());
                    } else {
                        stb.player.show_rec_icon(record);
                    }
                },
                this
            );

            //return rec_id;
        };

        this.remove_record_from_list = function (rec_id, show_msg) {
            _debug('pvr_local.remove_record_from_list', rec_id);

            var idx = stb.recordings.getIdxByVal('id', rec_id);

            _debug('idx', idx);

            if (idx === null) {
                return;
            }

            window.clearTimeout(stb.recordings[idx].start_timeout);
            window.clearTimeout(stb.recordings[idx].del_timeout);

            if (stb.player.is_tv) {
                if (stb.player.cur_tv_item.id == stb.recordings[idx].ch_id) {
                    stb.player.hide_rec_icon();
                }
            }

            if (show_msg) {

                var ch_idx = stb.player.channels.getIdxByVal("id", stb.recordings[idx].ch_id);

                if (ch_idx !== null) {
                    var channel_name = stb.player.channels[ch_idx].name;
                } else {
                    channel_name = '';
                }

                var program_name = stb.recordings[idx].program;
                stb.msg.push({
                    msg: get_word('rec_stop_msg').format(program_name, channel_name)
                })
            }

            pvrManager.RemoveTask(stb.recordings[idx].internal_id, 1);

            _debug('stb.recordings before', stb.recordings);
            stb.recordings.splice(idx, 1);
            _debug('stb.recordings after', stb.recordings);
        };

        this.get_clear_url = function (url) {
            _debug('pvr_local.get_clear_url', url);

            var arr = /(\S+:\/\/\S+)/.exec(url);

            if (arr && arr.length == 2) {
                return arr[1];
            }

            return false;
        };

        this.get_record_filename_for_program = function (program) {
            _debug('pvr_local.get_record_filename_for_program', program);

            var cur_prog = program.name;

            _debug('cur_prog', cur_prog);

            var start = new Date(parseInt(program.start_timestamp, 10) * 1000);

            var ch_idx = stb.player.channels.getIdxByVal("id", program.ch_id);

            if (ch_idx !== null) {
                var channel_name = stb.player.channels[ch_idx].name;
            } else {
                channel_name = '';
            }

            return start.getFullYear()
                + '' + this.format_date(start.getMonth() + 1)
                + '' + this.format_date(start.getDate())
                + '-' + this.format_date(start.getHours())
                + '' + this.format_date(start.getMinutes())
                + '' + this.format_date(start.getSeconds())
                + '_' + (channel_name + '_' + cur_prog).toTranslit()
                + '.mpg';
        };

        this.get_record_filename = function (channel) {
            _debug('pvr_local.get_record_filename', channel);

            var epg = stb.epg_loader.get_curr_and_next(channel.id);

            _debug('epg', epg);
            _debug('epg.length', epg.length);

            if (epg && epg.length > 0) {
                var cur_prog = epg[0].name || '';
            } else {
                cur_prog = '';
            }

            _debug('cur_prog', cur_prog);

            var now = new Date();

            return now.getFullYear()
                + '' + this.format_date(now.getMonth() + 1)
                + '' + this.format_date(now.getDate())
                + '-' + this.format_date(now.getHours())
                + '' + this.format_date(now.getMinutes())
                + '' + this.format_date(now.getSeconds())
                + '_' + (channel.name + '_' + cur_prog).toTranslit()
                + '.mpg';
        };

        this.format_date = function (param) {
            if (param < 10) {
                return '0' + param
            }
            return param
        };

        this.stop_channel_rec = function (ch) {
            _debug('pvr_local.stop_channel_rec', ch);

            var idx = stb.recordings.getIdxByVal('ch_id', ch.id);

            _debug('idx', idx);
            _debug('stb.recordings[idx]', stb.recordings[idx]);

            if (idx === null) {
                return;
            }

            var rec_id = stb.recordings[idx].id;

            if (idx !== null) {
                this.stop_confirm.rec_id = rec_id;
                this.stop_confirm.show();
            }
        };

        this.stop_rec = function (rec_id, callback) {
            _debug('pvr_local.stop_rec', rec_id);

            var idx = stb.recordings.getIdxByVal('id', rec_id);

            _debug('idx', idx);

            if (idx === null) {
                return;
            }

            stb.player.hide_rec_icon();

            pvrManager.RemoveTask(stb.recordings[idx].internal_id, 1);

            this.send_stop_rec(rec_id, false, callback);
        };

        this.send_stop_rec = function (rec_id, show_msg, callback) {
            _debug('pvr_local.send_stop_rec', rec_id);

            var idx = stb.recordings.getIdxByVal('id', rec_id);

            _debug('idx', idx);

            if (idx === null) {
                return;
            }

            stb.load(
                {
                    "type": "remote_pvr",
                    "action": "stop_record_on_stb",
                    "rec_id": stb.recordings[idx].id
                },
                function (result) {
                    _debug('on stop_record_on_stb', result);
                    this.remove_record_from_list(rec_id, show_msg);

                    if (callback) {
                        callback();
                    }
                },
                this
            );
        };

        this.del = function (real_rec_id, file, callback) {
            _debug('pvr_local.del', real_rec_id);

            var idx = stb.recordings.getIdxByVal('id', real_rec_id);

            if (idx !== null) {
                pvrManager.RemoveTask(stb.recordings[idx].internal_id, 3);
                this.remove_record_from_list(real_rec_id);
            } else {
                var rm_result = stb.RDir('RemoveFile "' + file + '"');
                var rm_tmp_result = stb.RDir('RemoveFile "' + file + '.tmp.ts"');
                _debug('rm_result', rm_result);
                _debug('rm_tmp_result', rm_tmp_result);
            }

            stb.load(
                {
                    "type": "remote_pvr",
                    "action": "del_record_on_stb",
                    "rec_id": real_rec_id
                },
                function (result) {
                    _debug('on del_record_on_stb', result);

                    if (callback) {
                        callback();
                    }
                },
                this
            );
        };

        this.is_error = function (result) {
            _debug('pvr_local.check_for_errors', result);

            if (result < 0) {
                if (this.error_codes.hasOwnProperty(result)) {
                    stb.notice.show(this.error_codes[result]);
                } else {
                    stb.notice.show(get_word('pvr_error_unknown'));
                }
                return true;
            }

            return false;
        };

        this.handle_error = function (rec_id) {
            _debug('pvr_local.handle_error', rec_id);

            var task = pvrManager.GetTaskByID(rec_id);

            _debug('task', task);

            task = JSON.parse(task);

            if (task && task.hasOwnProperty('errorCode')) {
                this.is_error(task.errorCode);
            }
        };

        this.remove_all_with_errors = function () {
            _debug('pvr_local.remove_all_active');

            var active_tasks = JSON.parse(pvrManager.GetAllTasks()) || [];
            _debug('active_tasks', active_tasks);

            var need_ro_remove = active_tasks.filter(function (task) {
                return task.state == 3;
            });

            _debug('need_ro_remove', need_ro_remove);
            _debug('stb.recordings', stb.recordings);

            var self = this;

            need_ro_remove.map(function (task) {

                var idx = stb.recordings.getIdxByVal('file', task.fileName);

                _debug('idx', idx);

                if (idx !== null) {
                    self.send_stop_rec(stb.recordings[idx].id);
                }

                return task;
            });
        };
    }

    module.pvr_local = new PvrLocal();

    if (typeof (pvrManager) != "undefined") {
        _debug('stb.user[max_local_recordings]', stb.user['max_local_recordings']);
        pvrManager.SetMaxRecordingCnt(parseInt(stb.user['max_local_recordings'], 10));
        var active_tasks = JSON.parse(pvrManager.GetAllTasks()) || [];
    } else {
        active_tasks = [];
    }

    _debug('active_tasks', active_tasks);

    _debug('stb.recordings before', stb.recordings);

    stb.recordings.map(function (record) {

        var now_ts = Math.ceil(new Date().getTime() / 1000);

        if (record.local == 1 && active_tasks.getIdxByVal('fileName', record.file) === null && now_ts > record.t_start_ts) { // remove old
            _debug('remove old', record);

            module.pvr_local.send_stop_rec(record.id);

        } else if (record.local == 1 && now_ts < record.t_start_ts) { // deferred
            _debug('restore deferred', record);

            var ch_idx = stb.player.channels.getIdxByVal("id", record.ch_id);

            module.pvr_local.remove_record_from_list(record.id);

            if (ch_idx !== null) {
                module.pvr_local.create(
                    stb.player.channels[ch_idx],
                    record.file,
                    record.t_start_ts,
                    record.t_stop_ts,
                    {
                        "name": record.program,
                        "id": record.program_id,
                        "real_id": record.program_real_id
                    }
                );
            }
        } else if (record.local == 1 && now_ts > record.t_start_ts && now_ts < record.t_stop_ts) { // restore current
            _debug('restore current', record);

            var idx = stb.recordings.getIdxByVal('id', record.id);

            if (idx === null) {
                return record;
            }

            var del_timeout = (record.t_stop_ts - record.t_start_ts) * 1000;

            _debug('del_timeout', del_timeout);

            stb.recordings[idx].del_timeout = window.setTimeout(function () {
                _debug('delete rec');
                module.pvr_local.send_stop_rec(record.id, true);
            }, del_timeout);
        }

        return record;
    });

    _debug('stb.recordings after', stb.recordings);

})();

loader.next();