// ***************************************************************************************************
// * (C) 2004 Pepperstream B.V.
// *
// * Project      : Container plugin: Nieuwsbrief
// * Auteur       : Aldo Quispel
// * Aangemaakt   : 10-06-2004
// * File         : nieuwsbrief.js
// * Omschrijving : In dit bestand staan de JavaScript functies die nodig zijn om de formulieren die
// *                de gebruiker ziet bij het aan- en afmelden juist te laten functioneren.
// ***************************************************************************************************
    var x;
    var y;

// *****************************************************************************
// Maak nieuwsbrief acties
// *****************************************************************************

    function checkVerstuur(submitknopid, zetklaarstring, verstuurstring) {
        // *****************************************************************************
        // * Omschrijving : Kijkt of alle velden van het versturen op zijn ingevult. Zo ja,
        // *                dan wordt de submit knop omgenoemt van
        // * Input        : submitknopid (string)  : Id van de submit knop voor versturen.
        // *                zetklaarstring (string): De tekst voor de knop bij klaarzetten/inplannen
        // *                verstuurstring (string): De tekst voor de knop bij versturen.
        // * Auteur       : Aldo Quispel
        // * Aangemaakt   : 8/27/2004 2:46PM
        // *****************************************************************************

        if ((document.getElementById('versturen_op_dag').value != '') &&
            (document.getElementById('versturen_op_maand').value != '') &&
            (document.getElementById('versturen_op_jaar').value != '')) {

            document.getElementById(submitknopid).value = zetklaarstring; //button label
            document.getElementById('klaarzetten').value = 'true'; //dat het niet meteen verstuurd mag worden.
        } else {
            if (document.getElementById(submitknopid).value != verstuurstring) {
                document.getElementById(submitknopid).value = verstuurstring; //button label
            }
            document.getElementById('klaarzetten').value = 'false'; //dat het meteen verstuurd mag worden.
        }

    }

    function bouwNBStijlBox() {
    // *****************************************************************************
    // * Omschrijving : Bouwd de Stijl tag selectie box op voor de nieuwsbrief.
    // *                Dit is waar stijlbox met css tags (in dit geval style tags)
    // *                ala de werking die container's editor ook kent.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/14/2004 1:41PM
    // *****************************************************************************

        var Stijl       = document.styleSheets;
        var selectbox   = document.getElementById('css_inhoud');
        var editor      = document.getElementById('inhoud');
        var fontkleurgevonden   = false;
        var achtergrondgevonden = false;
        var fontfamiliegevonden = false;
        var fontgrotegevonden   = false;
        var selectorText        = false;

        selectboxteller = 1;
        currentstijlid  = document.getElementById('currentstijl').value;

        if (selectbox.options.length > 0) {
            selectbox.options[0].text="> " + taal['opmaak'];
        }
        else {
            selectbox.options[0] = new Option("> " + taal['opmaak'], "");
        }
        selectbox.options[1] = new Option(":: "+taal['normaal'], "normaal");

        for(i=0;i<Stijl.length;i++) {
            if (Stijl[i].id == currentstijlid) {
                for(j=0;j<Stijl[i].rules.length;j++) {
                    //De opmaak box opbouwen
                    if ((Stijl[i].rules[j].style.tag != undefined) && (Stijl[i].rules[j].style.tag != "body")) {
                        selectboxteller++;
                        selectbox.options[selectboxteller] = new Option(Stijl[i].rules[j].style.tag, Stijl[i].rules[j].style.tag);
                        selectbox.options[selectboxteller].text = ":: "+Stijl[i].rules[j].style.desc;
                    }

                    //De class of stijl van de rich text editor bepalen
                    if (Stijl[i].rules[j].style.tag == "body") {
                        cssclassName = Stijl[i].rules[j].selectorText;
                        if (cssclassName != 'body') {
                            //het is een normale class, gebruikt die
                            selectorText = true;
                            cssclassName = cssclassName.substr(1);

                        }

                        //Het staat op de body, pak er enkel aantal waardes uit
                        if (Stijl[i].rules[j].style.backgroundColor) {
                            achtergrond = Stijl[i].rules[j].style.backgroundColor;
                            achtergrondgevonden = true;
                        }
                        if (Stijl[i].rules[j].style.color) {
                            fontkleur = Stijl[i].rules[j].style.color;
                            fontkleurgevonden = true;
                        }
                        if (Stijl[i].rules[j].style.fontFamily) {
                            fontfamilie = Stijl[i].rules[j].style.fontFamily;
                            fontfamiliegevonden = true;
                        }
                        if (Stijl[i].rules[j].style.fontSize) {
                            fontgrote = Stijl[i].rules[j].style.fontSize;
                            fontgrotegevonden = true;
                        }

                    }
                }
            }
        }

        if (selectorText == true) {
            editor.className = cssclassName;
        }

        //Reset waardes uit editDoc van admin.css
        editor.style.backgroundImage = "none";
	    editor.style.border          = '1px solid gray'
	    editor.style.padding         = '4px';
	    editor.style.left            = '5px';
	    editor.style.width           = '100%';
	    editor.style.overflow        = 'auto';
	    editor.style.marginTop       = '3px';

        if (achtergrondgevonden == true) {
            editor.style.background = achtergrond;
        }
        if (fontkleurgevonden == true) {
            editor.style.color = fontkleur;
        }
        if (fontfamiliegevonden == true) {
            editor.style.fontFamily = fontfamilie;
        }
        if (fontgrotegevonden == true) {
            editor.style.fontSize = fontgrote;
        }

    }

function switchNBStijl(stijlselectbox) {
    // *****************************************************************************
    // * Omschrijving : Switched tussen de verschillend aanwezige <STYLE> elementen
    // *                naar gelang de selectie van de gebruiker. Dit gebeurd door ze
    // *                respectievelijk op disabled = true of disabled = false te zetten.
    // * Input        : stijlselectbox (object) : de stijlselectbox
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/14/2004 9:53AM
    // *****************************************************************************

    nieuwstijlid     = stijlselectbox.options[stijlselectbox.options.selectedIndex].value;
    currentstijlid   = document.getElementById('currentstijl').value;

    var currentstijl = document.getElementById(currentstijlid);
    var nieuwsestijl = document.getElementById(nieuwstijlid);

    currentstijl.disabled = true;
    nieuwsestijl.disabled = false;

    document.getElementById('currentstijl').value = nieuwstijlid;

    bouwNBStijlBox();
}

function switchNB(querystring, selectbox) {
    // *****************************************************************************
    // * Omschrijving : Regeerd op het veranderen van de nieuwsbrief groep en
    // *                zet de location zodat de juiste nieuwsbrief groep herkend
    // *                wordt.
    // * Input        : querystring (string): string die achter ?a= komt.
    // *                selectbox (object)  : object van de selectbox van NB groepen.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/8/2004 1:53PM
    // *****************************************************************************

    //Sla eventueel ingevulde text op in een cookie.. ";" mag niet in cookie, dus tmp omschrijven.
    richtxt2hidden();

    var inhoud = encodeBase64(document.getElementById('inhoud_tmp').value);

    document.cookie = "NbriefInhoud=" + inhoud;
    document.cookie = "NbriefOnderwerp=" + document.getElementById('onderwerp').value

    if (document.getElementById('versturen_op_jaar')) {
        document.cookie = "NbriefDatum=" + document.getElementById('versturen_op_jaar').value+"-"+document.getElementById('versturen_op_maand').value+"-"+document.getElementById('versturen_op_dag').value
    }

    if (document.getElementById('nb_id')) {
        uriadd = "&id="+document.getElementById('nb_id').value;
    } else {
        uriadd = "";
    }

    window.location = "?a="+querystring+"&nbgid="+selectbox.options[selectbox.options.selectedIndex].value+uriadd;
}

function verzamelInhoud() {
    // *****************************************************************************
    // * Omschrijving : Toont een modeldialog voor het verzamelen van inhoud/samen-
    // *                vattingen. Deze worden hierna in de editor terug gezet.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/12/2004 2:39PM
    // *****************************************************************************
    var inhoud;

    samenvatting = window.showModalDialog("system/html/frame.html?a=toonVerzamelInhoud",null,"dialogWidth=500px;dialogHeight=300px;help:no;resizable:no;status:no");

    inhoud = '';

    //Lees de array uit
    if (samenvatting) {
        for (i=0;i<samenvatting.length;i++) {
            inhoud = inhoud + samenvatting[i];
        }

        //Paste in editor
        document.getElementById('inhoud').focus();
        var sel = document.selection.createRange();
        sel.pasteHTML(inhoud);
    }
}

function verwerkTransportbox() {

    var transportbox = document.getElementById('trn_uverzamel');
    ids = "";

    for (i=0;i<transportbox.options.length;i++) {
        ids = ids+transportbox.options[i].value+"#";
    }
     document.getElementById('verzameluit').value = ids;

}

function preview() {
// *****************************************************************************
// * Omschrijving : Toont een preview window van de te versturen nieuwsbrief.
// * Auteur       : Aldo Quispel
// * Aangemaakt   : 7/13/2004 10:03AM
// *****************************************************************************

    richtxt2hidden();
    zetMethod();

    document.tweede.action = '?a=cnb_preview';
    document.tweede.submit();
}

function verstuur() {
    // *****************************************************************************
    // * Omschrijving : verstuur de nieuwsbrief daadwerkelijk.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/13/2004 10:15AM
    // *****************************************************************************

    if (toonBevestingsPopup() == true) {
        richtxt2hidden();

        zetMethod();
        if (document.getElementById('klaarzetten')) {
            if (document.getElementById('klaarzetten').value == 'true') {
                document.tweede.action = 'post.php?a=cnb_zetklaar';
            } else {
                document.tweede.action = 'plugins/nieuwsbrief/postnieuwsbrief.php';
            }
        } else {
                document.tweede.action = 'plugins/nieuwsbrief/postnieuwsbrief.php';
        }

        postWindow();

        document.tweede.submit();
    }
}

function zetMethod() {
    // *****************************************************************************
    // * Omschrijving : Zet de method en target goed van het formulier "tweede"
    // *                zodat deze alsnog goed verstuurd kan worden als er op
    // *                preview of verstuur gedrukt wordt. Dit omdat er geen "eerste"
    // *                formulier is in het geval van de NB en we code hergebruiken van
    // *                Container om de richtexteditor te schrijven.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/13/2004 10:08AM
    // *****************************************************************************

    document.tweede.target = 'post';
    document.tweede.method = 'POST';
}

function richtxt2hidden() {
    // *****************************************************************************
    // * Omschrijving : Zet de inhoud uit de richt-text editor box in een hidden
    // *                form input die we wel kunnen posten.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/13/2004 10:10AM
    // *****************************************************************************

    setTablestyle('off');

    if (document.getElementById('inhoud').displayMode=='CODE') {
        //Zitten in code view.
       document.tweede.inhoud_tmp.value = document.getElementById('inhoud').innerText;
    }
    else {
        //Zitten in rich view.
       document.tweede.inhoud_tmp.value = document.getElementById('inhoud').innerHTML;
    }

}

// *****************************************************************************
// Popups - samenvatting
// *****************************************************************************
var collectiecounter = 0;

function lijstVoegToe(button) {
// *****************************************************************************
// * Omschrijving : De plusknop bij het toevoegen van lijstjes.
// * input        : button  - object van button waar op geklikt wordt.
// * Auteur       : Aldo Quispel (gebaseerd op code van Jan-loek Siskens)
// *****************************************************************************

    newhtml = new String();
    html = new String();

    html = button.parentElement.innerHTML;

    html = html.replace(/\n/g,"");
    html = html.replace(/\r/g,"");

    collectiecounter++;

    comment = /<!-- .* -->/
    newhtml = html.match(comment);
    newhtml = newhtml[0];

    newhtml = newhtml.replace(/<!-- /g,"");
    newhtml = newhtml.replace(/ -->/g,"");

    if (newhtml) {
        var retr = new RegExp ('.*<tr[^>]*>','gi');
        var retd = new RegExp ('.*<td[^>]*>','gi');
        table = document.getElementById('inserttabel');

        atr = newhtml.split ("</tr>");
        last = atr.pop();

        for (j=0;j<atr.length;j++) {
            strtr = atr[j].replace(retr,"");
            atd = strtr.split ("</td>");

            tr = table.insertRow();
            tr.className = "admin";

            for (i=0;i<atd.length;i++) {
                strtd = trim(atd[i].replace(retd,""));
                strtd = strtd.replace(/###/g,collectiecounter);

                if (strtd != "") {
                    td = tr.insertCell();
                    td.className = "admin";

                    td.innerHTML = strtd;
                }
            }
        }
    }
}

function lijstWis(button) {
// *****************************************************************************
// * Omschrijving : De wis knop bij het toevoegen van lijstjes
// * input        : button  - object van button waar op geklikt wordt.
// * Auteur       : Aldo Quispel
// *****************************************************************************

    tr = button.parentElement.parentElement;
    table = document.getElementById('inserttabel');

    table.deleteRow(tr.rowIndex);
}

// *****************************************************************************
// Beheer acties
// *****************************************************************************

function verwijderRecord(id, actie, terugnaar) {
    // *****************************************************************************
    // * Omschrijving : Via een verwijder knop een verwijder actie op een record
    // *                uitvoeren (abonnees of nieuwsbrieven);
    // * Input        : id (string)      : te wissen id
    // *                actie (string)   : de actie binnen post.php
    // *                terugnaar(string): waar naar terug ge-refered moet worden na
    // *                                   de post actie.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/7/2004 10:43AM
    // *****************************************************************************

    if (toonBevestingsPopup() == true) {

        bepaalMiddenScherm();

        pwindow = window.open("","post","top="+y+",left="+x+",dependent=yes,directories=no,height=200,location=no,menubar=no,personalbar=no,resizable=no,status=no,titlebar=yes,toolbar=no,width=300");
        pwindow.document.write("<html><head><title>"+taal['versturen']+"</title></head><link rel=\"stylesheet\" href=\"system/css/admin.css\" type=\"text/css\" title=\"admin\"><body bgcolor=\"#DFDEED\"><br><br><div class=\"admin\" align=\"center\">"+taal['versturen body']+"</div></body></html>");

        pwindow.location = "post.php?a="+actie+"&wisid="+id+"&terugnaar="+terugnaar;
    }
}

function bepaalMiddenScherm() {
    // *****************************************************************************
    // * Omschrijving : bepaald ongeveer het midden van het scherm van de bezoeker.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 6/30/2004 2:32PM
    // *****************************************************************************

    //Bepaal het midden van het scherm
    x = (screen.availWidth/2)-150;
    y = (screen.availHeight/2)-100;
}

function verwerkBevesting(keuze) {
    // *****************************************************************************
    // * Omschrijving : Sluit het bevestingswindow en geeft false terug op keuze "nee"
    // *                en true terug op keuze "ja"
    // * Input        : keuze (boolean) : true voor ja, false voor nee.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 6/30/2004 2:58PM
    // *****************************************************************************

    window.returnValue = keuze;
    window.close();
}

function toonBevestingsPopup() {
    // *****************************************************************************
    // * Omschrijving : Vraagt de gebruiker om bevesting van zijn of haar actie.
    // * Output       : gebruikerkeuze (boolean): keuze van de gebruiker of deze het
    // *                                          het zeker weet. True: ja, False: nee.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 6/30/2004 2:50PM
    // *****************************************************************************

    //Bepaal het midden van het scherm
    bepaalMiddenScherm()

    //Open een popup window
    gebruikerkeuze = window.showModalDialog("?a=toonbevestiging",null,"dialogWidth=200px;dialogHeight=100px;help:no;resizable:no;status:no");

    return gebruikerkeuze;
}

function toonAbonneeWissenConformatie(abonneeid, nbid) {
    // *****************************************************************************
    // * Omschrijving : Maakt een popup aan om het ontkoppelen van een abonnee en een
    // *                nieuwsbrief te bevestigen.
    // * Input        : aboneeid (string): id van de abonnee.
    // *                nbid (string)    : id van de nieuwsbrief.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 6/29/2004 4:11PM
    // *****************************************************************************

    //Onthoud de reeds ingevulde informatie
    onthoudNieuwsbriefInfo(nbid);

    //Bepaal het midden van het scherm
    bepaalMiddenScherm();

    //Open een popup window
    window.open("?a=bevwisabonee&abonneeid="+abonneeid+"&nbid="+nbid,"AbonneConformatie","top="+y+",left="+x+",width=250,height=150,dependent=yes,directories=no,location=no,menubar=no,personalbar=no,resizable=no,status=no,titlebar=no,toolbar=no");

}

function toonWijzigAbonneePopup(abonneeid, nbid) {
    // *****************************************************************************
    // * Omschrijving : Opened een popup waarin een individuele abonnee aangepast kan
    // *                worden.
    // * Input        : abonneeid (string): id van de abonnee
    // *                nbid (string)     : id van de nieuwsbrief
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/1/2004 3:05PM
    // *****************************************************************************

    //Onthoud de reeds ingevulde informatie
    if (nbid != '') {
        onthoudNieuwsbriefInfo(nbid);
    }

    //Bepaal het midden van het scherm
    bepaalMiddenScherm();

    //Open een popup window
    ouder = window.open("?a=wijzigaboneepopup&abonneeid="+abonneeid,"AbonneWijzigen","top="+y+",left="+x+",width=350,height=250,dependent=yes,directories=no,location=no,menubar=no,personalbar=no,resizable=yes,status=no,titlebar=no,toolbar=no,scrollbars=yes");

}

function controleNBleeg() {
    // *****************************************************************************
    // * Omschrijving : Controleerd of alle nieuwsbrieven zijn uitgezet bij de
    // *                abonnee en zo ja wordt er gevraagt of de gebruiker hier wel
    // *                zeker van is. Dit omdat de abonnee dan uit het systeem gewist
    // *                wordt.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/2/2004 9:12AM
    // *****************************************************************************

    minimaal1nb = false;
    checkboxes = document.getElementsByTagName("input");

    for (i=0; i< checkboxes.length; i++) {
        if (checkboxes[i].name.substr(0, 2) == "nb") {
            if (checkboxes[i].checked == true) {
                minimaal1nb = true;
            }
        }
    }

    if (minimaal1nb == false) {
        //Geen nieuwsbrieven geselecteerd, vraag gebruiker om bevestiging.
        gebruikerkeuze = window.showModalDialog("?a=toonbevestiging",null,"dialogWidth=200px;dialogHeight=100px;help:no;resizable:no;status:no");
    }
    else {
        //Wel nieuwsbrieven geselecteerd, dus true.
        gebruikerkeuze = true;
    }
    return gebruikerkeuze;

}

function refererUitURLParent() {
    // *****************************************************************************
    // * Omschrijving : Zet de URL van een parent om in een stukje refer nodig voor
    // *                post om te weten waar de "refresh" naartoe moet gebeuren.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/7/2004 10:19AM
    // *****************************************************************************

    referer = window.opener.location;
    referer = referer.toString();
    referer = referer.substr((referer.indexOf("?a=")+1));

    return referer;
}

function haalParentRefererOp() {
    // *****************************************************************************
    // * Omschrijving : Haal de url string op van het parent window zodat deze
    // *                gebruikt kan worden als referer bij het sluiten.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 7/1/2004 5:22PM
    // *****************************************************************************

    referer = refererUitURLParent();
    document.getElementById('referer').value = referer;
}

function onthoudNieuwsbriefInfo(nbid) {
    // *****************************************************************************
    // * Omschrijving : Onhoud alle gegevens die de gebruiker heeft opgegeven voor een reload.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 6/29/2004 4:11PM
    // *****************************************************************************

    gegevens = new Array('naam', 'beschrijving');

    info = "nbid="+nbid;

    for (i=0; i< gegevens.length; i++) {
        info = info + "#" + gegevens[i] + "=" + document.getElementById(gegevens[i]).value;
    }

    info = info + "#toonopform=" + document.getElementById('toonopform').checked;

    checkboxes = document.getElementsByTagName("input");

    for (i=0; i< checkboxes.length; i++) {
        if (checkboxes[i].name.substr(0, 5) == "stijl") {
            info = info + "#" + checkboxes[i].name + "=" + checkboxes[i].checked;
        }
    }

    document.cookie = "NbriefInfo=" + info;
}

// *****************************************************************************
// Bezoeker actie functies
// *****************************************************************************

function toonNieuwsbriefInfo(nieuwsbriefid, currentpageid, breedte, hoogte) {
    // *****************************************************************************
    // * Omschrijving : Toont een popup scherm met daarin een beschrijving van de
    // *                gekozen nieuwsbrief. Het renderen van de daadwerkelijke
    // *                beschrijving gebeurd in PHP.
    // * Auteur       : Aldo Quispel
    // * Aangemaakt   : 10-06-2004
    // *****************************************************************************

    //Bepaal het midden van het scherm
    bepaalMiddenScherm()

    //Open een popup window
    window.open("?id="+currentpageid+"&nieuwsbriefdescid="+nieuwsbriefid,"nieuwsbriefdesc","top="+y+",left="+x+",width="+breedte+",height="+hoogte+",dependent=yes,directories=no,location=no,menubar=no,personalbar=no,resizable=no,status=no,titlebar=yes,toolbar=no");
}

// *****************************************************************************
// Support
// *****************************************************************************

function trim(value) {
// *****************************************************************************
// * Omschrijving : Trim functie ala PHP/VB/etc.
// * Input        : value (string): string die getrimmed moet worden.
// * Output       : temp (string) : de getrimde string.
// * Auteur       : Aldo Quispel
// *                Gebaseerd op code gevonden op internet van Breaking Par Consulting Inc
// *                http://www.breakingpar.com/bkp/home.nsf/Doc!OpenNavigator&87256B280015193F87256C0C0062AC78
// * Aangemaakt   : 7/12/2004 11:16AM
// *****************************************************************************

    var temp = value;
    var obj = /^(\s*)([\W\w]*)(\b\s*$)/;

    if (obj.test(temp)) {
        temp = temp.replace(obj, '$2');
    }

    var obj = / +/g;

    temp = temp.replace(obj, " ");

    if (temp == " ") {
        temp = "";
    }

    return temp;
}

// **** base 64 encoding ****
//
// Code obtained from:
// http://ostermiller.org/calc/encode.html
// Written by Stephen Ostermiller
// Copyright (C) 2003 Stephen Ostermiller
//
// This program is free software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// http://www.gnu.org/copyleft/gpl.html
//
// ****

var END_OF_INPUT = -1;

var base64Chars = new Array(
    'A','B','C','D','E','F','G','H',
    'I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X',
    'Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n',
    'o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9','+','/'
);

var base64Str;
var base64Count;

function setBase64Str(str){
    base64Str = str;
    base64Count = 0;
}

function readBase64(){
    if (!base64Str) return END_OF_INPUT;
    if (base64Count >= base64Str.length) return END_OF_INPUT;
    var c = base64Str.charCodeAt(base64Count) & 0xff;
    base64Count++;
    return c;
}

function encodeBase64(str){
    setBase64Str(str);
    var result = '';
    var inBuffer = new Array(3);
    var lineCount = 0;
    var done = false;
    while (!done && (inBuffer[0] = readBase64()) != END_OF_INPUT){
        inBuffer[1] = readBase64();
        inBuffer[2] = readBase64();
        result += (base64Chars[ inBuffer[0] >> 2 ]);
        if (inBuffer[1] != END_OF_INPUT){
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
            if (inBuffer[2] != END_OF_INPUT){
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
                result += (base64Chars [inBuffer[2] & 0x3F]);
            } else {
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c)]);
                result += ('=');
                done = true;
            }
        } else {
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30)]);
            result += ('=');
            result += ('=');
            done = true;
        }
        lineCount += 4;
        if (lineCount >= 76){
            result += ('\n');
            lineCount = 0;
        }
    }
    return result;
}