/*
* utility functions 
*
* parameter:    Boolean duepTabsNachGanzLinks // optional parameter; can be omitted.  places tabs in front of all other tabs
*/

// init parameters
 if (typeof (duepTabsNachGanzLinks) == "undefined" || !(duepTabsNachGanzLinks === true || duepTabsNachGanzLinks === false))
  {
    duepTabsNachGanzLinks = false; //standardsetting to false
  }



MiniUtil = {
    /** remove a Node form the DOM */
    removeNode: function(el) {
        el.parentNode.removeChild(el);
    },

    imageView: function() {
        var urlParams   = this.urlParams();
        return wgCanonicalNamespace === "File"
                && urlParams !== "edit"
                && urlParams !== "submit";
    },

    imageEdit: function() {
        var urlParams   = this.urlParams();
        return wgCanonicalNamespace === "File"
                && urlParams === "edit";
    },

    /** decode url-parameters into a map */
    urlParams: function() {
        if (location.search === "")  return {};
        var out = {};
        location.search.substring(1).split("&")
        .forEach(function(param) {
            var parts   = param.split("=");
            if (parts.length !== 2)  return;
            var key     = decodeURIComponent(parts);
            var code    = parts.replace(/\+/g, "%20");
            out    = decodeURIComponent(code);
        });
        return out;
    },

    /** create a link executing a function when clicked */
    jsLink: function(label, clicked) {
        var span = document.createElement("span");
        span.textContent = label;
        var a   = document.createElement("a");
        a.appendChild(span);
        a.onclick       = clicked;
        a.style.cursor  = "default";
        return a;
    },

    /** adds a tab executing a function when clicked */
    addJsTab: function(label, clicked) {
        var span = document.createElement("span");
        var a   = this.jsLink(label, clicked);
        span.appendChild(a);
        var li  = document.createElement("li");
        li.appendChild(span);
        li.className = "collapsible";

        if (duepTabsNachGanzLinks) {  // if duepTabsNachGanzLinks is set to "true" ...
         $("#p-cactions ul").prepend(li); // places tabs in front of all other tabs
        } else {
         $("#p-cactions ul").append(li);  // places tabs after all other tabs
        }

    },

    /** asks for a reason, and asks again if empty */
    promptReason: function(text) {
        for (;;) {
            var reason = prompt(text);
            if (reason !== "")   return reason;
            if (reason === null) return null;
        }
    },

    /** create a function reloading the current page */
    reloader: function() {
        return function() {
            window.location.href    = MiniWiki.pageURL(wgPageName);
        };
    }
};

/** minimal mediawiki api */
MiniWiki = {
    /** returns the url of a page in read-mode */
    pageURL: function(title) {
        return wgArticlePath.replace(/\$1/, this.encodeTitle(title));
    },

    /** returns the url of an arbitrary page */
    scriptURL: function(params) {
        return wgScript + "?" + MiniAjax.urlEncode(params);
    },

    /** encode a page title so it can be used in an URL */
    encodeTitle: function(title) {
        return encodeURIComponent(title.replace(/ /g, "_"))
                .replace(/%%/g,     "\u0000")
                .replace(/%3a/gi,   ":"     )
                .replace(/%2f/gi,   "/"     )
                .replace(/%23/gi,   "#"     )
                .replace(/\u0000/,  "%%"    );
    },

    //------------------------------------------------------------------------------
    //## edit

    /** add text to a page at the end and calls the finishedFunc if sucessful */
    appendText: function(title, text, subject, finishedFunc) {
        function change(form) {
            form.wpSummary  = subject;
            form.wpTextbox1 += text;
            form.wpSave     = true;
            return true;
        }
        this.editPage(title, null, change, finishedFunc);
    },

    /** add text to a page at the start and calls the finishedFunc if sucessful */
    prependText: function(title, text, subject, finishedFunc) {
        function change(form) {
            form.wpSummary  = subject;
            form.wpTextbox1 = text + form.wpTextbox1;
            form.wpSave     = true;
            return true;
        }
        this.editPage(title, null, change, finishedFunc);
    },

    /** replace a regexp on a page and calls the finishedFunc if sucessful */
    replaceText: function(title, search, replace, subject, finishedFunc) {
        function change(form) {
            form.wpSummary  = subject;
            form.wpTextbox1 = form.wpTextbox1.replace(search, replace);
            form.wpSave     = true;
            return true;
        }
        this.editPage(title, null, change, finishedFunc);
    },

    /**
     * uses a function to replace a page's text and calls the finishedFunc if sucessful.
     * changeFunc is called with the page's text and returns the new text or null to abort
     */
    changeText: function(title, changeFunc, subject, finishedFunc) {
        function change(form) {
            var newText = changeFunc(form.wpTextbox1);
            if (newText === null)    return false;
            form.wpTextbox1 = newText;
            form.wpSummary  = subject;
            form.wpSave     = true;
            return true;
        }
        this.editPage(title, null, change, finishedFunc);
    },

    /** append a new section to a page and calls the finishedFunc if sucessful */
    newSection: function(title, text, subject, finishedFunc) {
        function change(form) {
            form.wpSummary  = subject;
            form.wpTextbox1 = text;
            form.wpSave     = true;
            return true;
        }
        this.editPage(title, "new", change, finishedFunc);
    },

    /** arbitrary page editing, calls the finishedFunc if sucessful */
    editPage: function(title, section, formChangeFunc, finishedFunc) {
        var args    = {
            title:      title,
            action:     "edit",
            section:    section
        };
        MiniAjax.get(wgScript, args, function(client) {
            if (client.status !== 200)   throw "expected status 200, got: " + client.status;

            // fetch form
// not needed anymore            var xml         = MiniAjax.parseXML(client.responseText);

            // does not work anymore with 1.19. Probably since the html is HTML5 now - replaced by next line
            //  "XML retrieved by invoking GET and POST methods on index.php is incompatible with HTML 5   You should update code to use api.php, JSON format and jQuery.ajax immediately." @https://www.mediawiki.orghttps://wiki95.com/de/ResourceLoader/JavaScript_Deprecations  See also: http://www.ibm.com/developerworks/xml/tutorials/x-processxmljquerytut/x-processxmljquerytut-pdf.pdf
            //  var editform    = xml.getElementById("editform");
            var editform    = $('#editform', client.responseText).get(0);

            if (!editform)  throw "form editform not found";

            // extract form
            var action      = editform.action;
            var formData    = {
                wpTextbox1:     editform.elements.value,
                wpSummary:      editform.elements.value,
// Die Checkbox wpMinoredit gibts bei newSection nicht mehr. Einfach ganz aus nun:               wpMinoredit:    editform.elements.checked,
                wpWatchthis:    editform.elements.checked,
                wpSection:      editform.elements.value,
                wpEdittime:     editform.elements.value,
                wpEditToken:    editform.elements.value,
                wpStarttime:    editform.elements.value,
                wpScrolltop:    editform.elements.value,
                wpAutoSummary:  editform.elements.value,
                wpSave:         false,
                wpPreview:      false,
                wpDiff:         false
            };

            // change editform
            var save    = formChangeFunc(formData);
            if (!save)  return;

            // store editform
            MiniAjax.post(action, formData, function(client) {
                if (client.status !== 200)   throw "expected status 200, got: " + client.status;
                if (finishedFunc)   finishedFunc(client.responseText);
            });
        });
    },

    //------------------------------------------------------------------------------
    //## email

    sendEmail: function(user, subject, body, ccSelf, doneFunc) {
        var args = {
            title:  "Special:EmailUser",
            target: user
        };
        MiniAjax.get(wgScript, args, function(client) {
            if (client.status !== 200)   throw "expected status 200, got: " + client.status;

            // fetch form
// not needed anymore:            var xml     = MiniAjax.parseXML(client.responseText);


            // var form    = xml.getElementById("emailuser");   // see same error at same function above
            var form    =  $('form', client.responseText).get(0); //there is no id of this form anymore... try the first form on this page
            if (!form)  throw "form emailuser not found";
                        if ($('input',$('form', client.responseText)).length !== 1) { // checks that wpSubject is present in the form
                                    throw "wrong form emailuser found → not found";
                        }

            var formData    = {
                wpEditToken:    form.elements.value,
                wpSubject:      subject,
                wpTarget:       user,
                wpText:         body,
                wpCCMe:         ccSelf,
            };

            // store editform
            MiniAjax.post(form.action, formData, function(client) {
                if (client.status !== 200)   throw "expected status 200, got: " + client.status;
                if (doneFunc)   doneFunc(client.responseText);
            });
        });
    }
};

/** simple ajax helper */
MiniAjax = {
    /** GET from an URL, calls the okFunc if successful */
    get: function(url, params, okFunc) {
        var getURL  = url
                    + (url.indexOf("?") === -1 ? "?" : "&")
                    + this.urlEncode(params, false);
        var client  = new XMLHttpRequest();
        client.open("GET", getURL, true);
        client.onreadystatechange = function() {
            if (client.readyState !== 4) return;
            okFunc(client);
        };
        client.send(null);
    },

    /** POST to an URL, calls the okFunc if successful */
    post: function(url, params, okFunc) {
        var postBody    = this.urlEncode(params, true);
        var client      = new XMLHttpRequest();
        client.open("POST", url, true);
        client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        client.onreadystatechange = function() {
            if (client.readyState !== 4) return;
            okFunc(client);
        };
        client.send(postBody);
    },

    /** encodes a Map or Pair-Array into a query string, optionally for use with application/x-www-form-urlencoded  */
    urlEncode: function(params, form) {
             if (!params)                       params  = ;
        else if (params.constructor !== Array)   params  = this.mapToPairs(params);
        var encodeComponent = form ? this.encodeFormValue : encodeURIComponent;
        function encodePair(pair) { return pair.map(encodeComponent).join("="); }
        return params.map(encodePair).join("&");
    },

    /** encodes a single value for application/x-www-form-urlencoded */
    encodeFormValue: function(value) {
        return encodeURIComponent(value
                .replace(/\r\n|\n|\r/g, "\r\n"))
                .replace(/(^|)(%%)*%20/g, "$1$2+");
    },

    /** convert a map into an Array for 2-element Arrays */
    mapToPairs: function(params) {
        var out = ;
        for (key in params) {
			if (!params.hasOwnProperty(key))	continue;
            var val = params;
            if (val === null)   continue;
            if (val === false)  continue;
            if (val === true)   val = "1";
            val = val.toString();
            out.push();
        }
        return out;
    },

    // probably a unused function (at least by "düp setzen")!  Works but is simply may be not used.
    /** parse XML and XHTML content */
    parseXML: function(text) {
//        alert("This should not really be a used function");
        var xml = new DOMParser().parseFromString(text, "text/xml");
        var doc = xml.documentElement;
        if (doc.tagName === "parserError")   throw "XML parser error: " + doc.textContent;
        return xml;
    }
};