/// class PD.Web.MonitoredDownloadManager

PD.Web.MonitoredDownloadManager = Class.extend({

    _options: null,
    _dialog: null,
    _downloadTo: {
        window: null,
        iframe: null
    },
    _hasDialogBeenOpened: null,
    _elapsedMilliseconds: null,
    _isDownloadComplete: null,

    init: function (options) {

        this._elapsedMilliseconds = 0;
        this._hasDialogBeenOpened = false;
        this._isDownloadComplete = false;

        this._download = {
            window: null,
            iframe: null
        };

        this._options = $.extend({
            url: null,
            prepareCallback: function (url) { },
            successCallback: function (url) { },
            errorCallback: function (responseHtml, url, error) { },
            httpMethod: "GET",
            data: null,
            checkInterval: 100,
            cookieName: "fileDownload",
            cookieValue: "true",
            cookiePath: "/",
            cookieDomain: null,
        }, options);


        this.start();
    },

    get_options: function (id) {
        return this._options[id];
    },

    get_dialog: function () {
        return this._dialog;
    },

    start: function () {

        var downloadUrl = this.getDownloadUrl(),
            checkInterval = this.get_options("checkInterval");

        this.onDownloadPrepare();

        this.startDownload();

        setTimeout($.proxy(this.isDownloadComplete, this), checkInterval);
        setTimeout($.proxy(this.isDownloadComplete, this), checkInterval);

    },
    
    startDownload: function () {
        
        var downloadUrl = this.getDownloadUrl(),
            $iframe = $("#monitored_download_manager");

        $iframe.remove();
        $iframe = $("<iframe id='monitored_download_manager'>").hide().prop("src", downloadUrl).appendTo("body");
        
        this._downloadTo.iframe = $iframe;

    },
    
    cancelDownload: function () {
        
        var $iframe = $("#monitored_download_manager");

        $iframe.remove();
        //$iframe = $("<iframe id='monitored_download_manager'>").hide().prop("src", "about:blank").appendTo("body");
        this._downloadTo.iframe = null;
        this.closeDialog();

    },

    isDownloadComplete: function () {

        var downloadUrl = this.get_options("url"),
            checkInterval = this.get_options("checkInterval"),
            timeout = this.get_options("timeout") || 15000,
            hasDialogBeenOpened = this._hasDialogBeenOpened;

        this._elapsedMilliseconds += checkInterval;

        if (this._elapsedMilliseconds > timeout) {
            this.cancelDownload();
            return;
        }

        if (this.isDownloadSuccess()) {
            this.onDownloadSuccess(downloadUrl);
        }
        else {

            if (!this.isDownloadingToCurrentWindow()) {
                if (this.isDownloadError()) {
                    return;
                }
            }

            if (!hasDialogBeenOpened) {
                this.checkShouldOpenDialog();
            }

            if (!this._isDownloadComplete) {
                setTimeout($.proxy(this.isDownloadComplete, this), checkInterval);
            }
            
        }

    },

    onDownloadPrepare: function (url) {
        this.get_options("prepareCallback")(url);
    },

    onDownloadSuccess: function (url) {
        this._isDownloadComplete = true;
        this.get_options("successCallback")(url);
        this.closeDialog();
    },

    onDownloadError: function (responseHtml, url, error) {
        this.get_options("errorCallback")(responseHtml, url, error);
        this.showDialog();
        this.updateDialogMessage("An error has occurred.");
    },

    checkShouldOpenDialog: function () {
        
        var delayMilliseconds = 1000,
            elapsedMilliseconds = this._elapsedMilliseconds,
            checkInterval = this.get_options("checkInterval");
        
        if (this._isDownloadComplete || this._hasDialogBeenOpened) {
            return;
        }

        if (elapsedMilliseconds >= delayMilliseconds) {
            this.showDialog();
        }

    },

    showDialog: function () {

        var that = this;

        if (this._hasDialogBeenOpened) {
            return;
        }

        this._hasDialogBeenOpened = true;

        this._dialog = PD.Web.MonitoredDownloadManagerDialog.open({
            message: this.get_options("dialogMessage"),
            config: {
                title: this.get_options("dialogTitle"),
            },
            callbacks: {
                cancel: function (e) {
                    //that._dialog = null;
                }
            }
        });

    },

    updateDialogMessage: function (message) {

        var dialog = this.get_dialog();

        if (dialog != null) {
            this.get_dialog().updateMessage(message);
        }

    },

    closeDialog: function () {
        
        var dialog = this.get_dialog();

        if (dialog != null) {
            dialog.close()
            this._dialog = null;
        }

    },

    isDownloadSuccess: function () {

        var result = false,
            downloadUrl = this.get_options("url"),
            cookieName = this.get_options("cookieName"),
            cookieValue = this.get_options("cookieValue"),
            cookieDomain = this.get_options("cookieDomain"),
            cookiePath = this.get_options("cookiePath"),
            cookieData = cookieName + "=; path=" + cookiePath + "; expires=" + new Date(0).toUTCString() + ";";

        if (typeof cookieValue == 'string') {
            cookieValue = cookieValue.toLowerCase();
        }

        var lowerCaseCookie = cookieName.toLowerCase() + "=" + cookieValue.toLowerCase();

        if (document.cookie.toLowerCase().indexOf(lowerCaseCookie) > -1) {

            if (cookieDomain) {
                cookieData += " domain=" + cookieDomain + ";";
            }

            document.cookie = cookieData;

            result = true;

        }

        return result;

    },

    isDownloadingToCurrentWindow: function () {
        return this._downloadTo.window == null && this._downloadTo.iframe == null;
    },

    isDownloadError: function () {

        var that = this,
            downloadUrl = this.getDownloadUrl(),
            body = null;

        try {

            body = this.getDownloadDocumentBody();

            if (body) {
                setTimeout(function () {
                    that.onDownloadError(body.innerHTML, downloadUrl, "docbody");
                    that.cleanUp(true);
                }, 100);
            }

        }
        catch (e) {
            this.onDownloadError("", downloadUrl, e);
            this.cleanUp(true);
            return;
        }


    },

    getDownloadDocumentBody: function () {

        var result = null,
            downloadIFrame = this._downloadTo.iframe,
            downloadWindow = this._downloadTo.window,
            isIFrameDownload = downloadIFrame != null,
            isWindowDownload = downloadWindow != null,
            win = null,
            doc = null;

        if (isIFrameDownload) {
            win = downloadIFrame[0].contentWindow || downloadIFrame[0].contentDocument;
            if (win.document) {
                doc = win.document;
            }
        }
        else {
            doc = downloadWindow.document;
        }

        if (doc && doc.body !== null && doc.body.innerHTML.length) {
            result = doc.body;
        }

        return result;

    },

    cleanUp: function (isFailure) {
    },

    getDownloadUrl: function () {

        var result = null,
            url = this.get_options("url"),
            data = this.get_options("data");

        result = PD.Path.resolve(url);

        if (data !== null && typeof data !== "string") {
            data = $.param(data);
        }

        if (data !== null) {
            result += url.indexOf('?') > -1 ? "&" : "?" + data;
        }

        return result;

    }

});

PD.Web.MonitoredDownloadManager.download = function (url, params, options) {

    return new PD.Web.MonitoredDownloadManager($.extend({
        url: url,
        data: params
    }, options));

};