﻿(function() {

    var d = document, w = window;

    /**
    * Attaches event to a dom element
    */
    function addEvent(el, type, fn) {
        if (w.addEventListener) {
            el.addEventListener(type, fn, false);
        } else if (w.attachEvent) {
            var f = function() {
                fn.call(el, w.event);
            };
            el.attachEvent('on' + type, f)
        }
    }


    /**
    * Creates and returns element from html chunk
    */
    var toElement = function() {
        var div = d.createElement('div');
        return function(html) {
            div.innerHTML = html;
            var el = div.childNodes[0];
            div.removeChild(el);
            return el;
        }
    } ();


    /**
    * Function generates unique id
    */
    var getUID = function() {
        var id = 0;
        return function() {
            return 'ValumsAjaxUpload' + id++;
        }
    } ();


    AjaxFormSubmit = AjaxFormSubmit = function(form, options) {

        if (form.jquery) {
            form = form[0];
        }
        this._form = form;

        this._settings = {
            onComplete: function(response) { }
        };

        for (var i in options) {
            this._settings[i] = options[i];
        }
    }

    // assigning methods to our class
    AjaxFormSubmit.prototype = {

        /**
        * Creates iframe with unique name
        */
        _createIframe: function() {
            // unique name
            // We cannot use getTime, because it sometimes return
            // same value in safari :(
            var id = getUID();

            // Remove ie6 "This page contains both secure and nonsecure items" prompt 
            // http://tinyurl.com/77w9wh
            var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
            iframe.id = id;
            iframe.style.display = 'none';
            document.body.appendChild(iframe);
            return iframe;
        },
        /**
        * Upload file without refreshing the page
        */
        submit: function() {
            var self = this, settings = this._settings;

            // Create new iframe for this submission
            var iframe = this._createIframe();

            this._form.target = iframe.name;
            this._form.enctype = "multipart/form-data";
            this._form.encoding = "multipart/form-data";
            this._form.submit();


            var toDeleteFlag = false;

            addEvent(iframe, 'load', function(e) {

                if (// For Safari
					iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
                // For FF, IE
					iframe.src == "javascript:'<html></html>';") {

                    // First time around, do not delete.
                    if (toDeleteFlag) {
                        // Fix busy state in FF3
                        setTimeout(function() {
                            document.body.removeChild(iframe);
                        }, 0);
                    }
                    return;
                }

                var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;

                // fixing Opera 9.26
                if (doc.readyState && doc.readyState != 'complete') {
                    // Opera fires load event multiple times
                    // Even when the DOM is not ready yet
                    // this fix should not affect other browsers
                    return;
                }

                // fixing Opera 9.64
                if (doc.body && doc.body.innerHTML == "false") {
                    // In Opera 9.64 event was fired second time
                    // when body.innerHTML changed from false 
                    // to server response approx. after 1 sec
                    return;
                }

                var response;

                if (doc.XMLDocument) {
                    // response is a xml document IE property
                    response = doc.XMLDocument;
                } else if (doc.body) {
                    // response is html document or plain text
                    response = doc.body.innerHTML;
                } else {
                    // response is a xml document
                    var response = doc;
                }

                settings.onComplete.call(self, response);

                // Reload blank page, so that reloading main page
                // does not re-submit the post. Also, remember to
                // delete the frame
                toDeleteFlag = true;

                // Fix IE mixed content issue
                iframe.src = "javascript:'<html></html>';";
            });
        }
    };
})();
