(function (window, $) {
    'use strict';

    function CallView(template, handlers) {
        BaseView.apply(this);

        this._template = template;

        this._init();
        this._addHandlers(handlers);
    }

    CallView.prototype = Object.create(BaseView.prototype);

    CallView.prototype._init = function() {
        this.callId = this._template.find(".callId");

        this.call = this._template.find(".call");
        this.callPanel = this._template.find(".callPanel");
        this.callPanelTitle = this._template.find(".callPanelTitle");

        this.localVideo = this._template.find(".localVideo");
        this.remoteVideo = this._template.find(".remoteVideo");

        this.muteBtn = this._template.find(".muteBtn");
        this.unmuteBtn = this._template.find(".unmuteBtn");
        this.holdBtn = this._template.find(".holdBtn");
        this.unholdBtn = this._template.find(".unholdBtn");
        this.blockVideoBtn = this._template.find(".blockVideoBtn");
        this.unblockVideoBtn = this._template.find(".unblockVideoBtn");

        this.dialButtons = this._template.find(".dialButtons");
        this.dialpadTextBox = this._template.find(".dialpadTextBox");

        this.callTimer = this._template.find(".callTimer");
        this.callState = this._template.find(".callState");

        this.callWithAddress = this._template.find(".callWithAddress");
        this.callControlBtns = this._template.find(".callControlBtns");
        this.endCallBtn = this._template.find(".endCallBtn");
        this.videoPanel = this._template.find(".videoPanel");

        this.errorLog = $("#errorLog");
    };

    CallView.prototype._addHandlers = function (handlers) {
        this.endCallBtn.on('click', function () {
            handlers.handleEndCall();
        });

        this.muteBtn.on('click', function () {
            handlers.handleMuteUnmute();
        });

        this.unmuteBtn.on('click', function () {
            handlers.handleMuteUnmute();
        });

        this.holdBtn.on('click', function () {
            handlers.handleHoldUnholdCall();
        });

        this.unholdBtn.on('click', function () {
            handlers.handleHoldUnholdCall();
        });

        this.blockVideoBtn.on('click', function () {
            handlers.handleBlockUnblockVideo(true);
        });

        this.unblockVideoBtn.on('click', function () {
            handlers.handleBlockUnblockVideo(false);
        });
    };

    /**
     * Function show call created localy.
     *
     * @param {String} remoteAddress
     */
    CallView.prototype.showLocalCall = function (remoteAddress) {
        this.callPanel.show();

        this.callWithAddress.text('You call to: ' + remoteAddress);
        this.callControlBtns.show();
        this.endCallBtn.show();
    };

    /**
     * Function shows call control panel after the connection.
     *
     * @param {Object} call
     * @param {Boolean} hasVideo
     */
    CallView.prototype.showCallControlPanel = function (call, hasVideo) {
        console.log("Client: call established callback");
        this.callWithAddress.text('Call with ' + call.getRemoteAddress());
        this.callControlBtns.show();
        this.callPanelTitle.show();
        this.endCallBtn.show();
        this.muteBtn.show();
        this.holdBtn.show();
        this.dialButtons.show();

        if (hasVideo) {
            console.log("Client: Video offer SUPPORTED");
            this.videoPanel.show();
            this.blockVideoBtn.show();
        } else {
            this.videoPanel.hide();
            this.blockVideoBtn.hide();
            this.unblockVideoBtn.hide();
        }
    };

    /**
     * Function show call error.
     */
    CallView.prototype.showCallFailedInformation = function (err) {
        console.log("Client: Call failed");
        this.errorLog.append('<div>Call failed: ' + err + '</div>');
    };

    /**
     * Function show remote alerting.
     */
    CallView.prototype.showRemoteAlerting = function () {
        console.log("Client: Remote party alerting.......");
    };

    /**
     * Function hide call panel.
     */
    CallView.prototype.hideCallPanel = function () {
        console.log("Client: Call Ended Callback");
        this.callPanel.hide();
        this.callControlBtns.hide();
        this.callPanelTitle.hide();
        this.endCallBtn.hide();
        this.videoPanel.hide();
        this.muteBtn.hide();
        this.unmuteBtn.hide();
        this.holdBtn.hide();
        this.unholdBtn.hide();

        this.blockVideoBtn.hide();
        this.unblockVideoBtn.hide();

        this.dialButtons.hide();
    };

    /**
     * Function disable Ignore button.
     */
    CallView.prototype.disableIgnoreButton = function () {
        this.ignoreCallBtn.prop('disabled', true);
    };

    /**
     * Function change hold/unhold button.
     *
     * @param {Boolean} isHolded
     */
    CallView.prototype.changeHoldUnholdBtn = function (isHolded) {
        if (isHolded) {
            this.holdBtn.hide();
            this.unholdBtn.show();
        } else {
            this.holdBtn.show();
            this.unholdBtn.hide();
        }
    };

    /**
     * Function change mute/unmute button.
     *
     * @param {Boolean} isMuted
     */
    CallView.prototype.changeMuteUnmuteBtn = function (isMuted) {
        if (isMuted) {
            this.muteBtn.hide();
            this.unmuteBtn.show();
        } else {
            this.muteBtn.show();
            this.unmuteBtn.hide();
        }
    };

    /**
     * Function change block video button.
     *
     * @param {Boolean} isAllowed
     */
    CallView.prototype.changeBlockBtn = function (isAllowed) {
        if (isAllowed) {
            this.blockVideoBtn.show();
        } else {
            this.blockVideoBtn.hide();
        }
    };

    /**
     * Function change unblock video button.
     *
     * @param {Boolean} isAllowed
     */
    CallView.prototype.changeUnblockBtn = function (isAllowed) {
        if (isAllowed) {
            this.unblockVideoBtn.show();
        } else {
            this.unblockVideoBtn.hide();
        }
    };

    /**
     * Function change call state.
     *
     * @param {String} state
     */
    CallView.prototype.changeCallState = function (state) {
        this.callState.text(state);
    };

    /**
     * Function refresh call timer.
     *
     * @param {Number} timeInSeconds
     */
    CallView.prototype.refreshCallTimer = function (timeInSeconds) {
        var date = new Date(null);
        date.setSeconds(timeInSeconds);
        var timeString = date.toISOString().substr(11, 8);

        this.callTimer.text(timeString);
    };

    /**
     * Function clear call timer.
     */
    CallView.prototype.clearCallTimer = function () {
        this.callTimer.text("--:--:--");
    };

    /**
     * Function sets title kind of call.
     */
    CallView.prototype.setCallTitle = function () {
        this.call.text('Call');
    };

    CallView.prototype.setCallId = function (callId) {
        this.callId.text(callId);
    };

    /**
     * Function sets title kind of call.
     */
    CallView.prototype.setConferenceTitle = function () {
        this.call.text('Conference');
    };

    /**
     * Function set src parameter to local stream.
     *
     * @param {MediaStream} stream
     */
     CallView.prototype.setLocalStream = function (stream) { 
        var localVideoElement = this.localVideo.get(0);
        if (stream === null || localVideoElement.srcObject === null || localVideoElement.srcObject.id !== stream.id) {      
            localVideoElement.srcObject = stream;
        }
    };

    /**
     * Function set src parameter to remote stream.
     *
     * @param {MediaStream} stream
     */
    CallView.prototype.setRemoteStream = function (stream) {
        var remoteVideoElement = this.remoteVideo.get(0);
        if (stream === null || remoteVideoElement.srcObject === null || remoteVideoElement.srcObject.id !== stream.id) { 
            remoteVideoElement.srcObject = stream;
        }
    };

    window.CallView = CallView;

})(window, jQuery);
