/*   After experimenting with an XMLHttpRequest version, I've decided to migrate most of the index page content to JS.
 *   It's just easier, I think. I originally wanted it to be accessible both locally and on the server, because I wanted
 *  to be able to use it on the no-script pages. But they are so limited in functionality, I don't really need to anymore; 
 *  the only thing that will be used on both script and no-script pages is the downloads information. Which will now be 
 *  done with XMLHttpRequest. When the script page loads, the DL information will be inserted into a JS bank, so it can be 
 *  used on individual page thingies.
 *  
 *  index
 *      section (icon name is the same as the section id, plus _32 or _100)
 *          section header
 *          section pages (FCs etc) / section content (home, faq, etc)
 *          
 *  
 *  
 *  
 */

/* UTILITIES */

var oAltastic = {
    
    /* RESOURCES gleaned from the xml file */
    resources : {
        
        acronyms : {
            img : "Images",
            dox : "Documents, Printables & Guides",
            etc : "Miscellaneous"
        },
        
        loadResources : function () {
            
            //assuming we have something to work with, make a request
            var xmlhttp = $.getXmlHttpRequestObject();
            
            //when we get a response to our ajax query, deal with it.
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    
                    oAltastic.xmlDoc = xmlhttp.responseXML;
                    oAltastic.resources.populate();
                    
                }
            }
            xmlhttp.open("GET","downloads.xml",true);
            xmlhttp.send();
            
        },
        
        //returns object from resource bank whose id matches the query
        getPageDownloads : function (query) {
            
            try {
                return oAltastic.resources.bank[query];
            }
            catch (e) {
                return null;
            }
            
            return null;
        },
        
        //called once, onload. puts xml dls in js format, then clears the xmlDoc variable
        populate : function () {
            
            //get the list of dlsections, and create a new bank entry for each one such that the ids match
            var dlsections = oAltastic.xmlDoc.getElementsByTagName("dlsection");
            
            for (var i = 0; i < dlsections.length; i++) {
                var pageid = dlsections[i].getAttribute("id");
                
                oAltastic.resources.bank[pageid] = {};
                
                //add the group and section id to each page
                for (var t in oAltastic.bank) {
                    
                    for (var s in oAltastic.bank[t]) {
                        
                        if (oAltastic.bank[t][s]["page_" + pageid]) {
                            
                            //add a section if one does not already exist (we only need sections if we have pages with dls)
                            oAltastic.resources.bank[pageid].groupid = t;
                            oAltastic.resources.bank[pageid].sectid = s;
                            
                        }
                    }
                }
                
                //if there is still no group or section id, we are dealing with dox, so we do it manually
                if ( (!oAltastic.resources.bank[pageid].sectid) && (!oAltastic.resources.bank[pageid].groupid) ) {
                    oAltastic.resources.bank[pageid].groupid = "group_prep";
                    oAltastic.resources.bank[pageid].sectid = "section_resources";
                }
                
                var dls = dlsections[i].getElementsByTagName("dl");
                for (var d = 0; d < dls.length; d++) {
                    
                    //add image, document and offliner subsections to each dlsection and add the dls to those]
                    var dltype = dls[d].getAttribute("type");
                    
                    if (dltype == "image") {
                        //if there is no subsection in the bank, make one
                        if (!oAltastic.resources.bank[pageid].img) {
                            oAltastic.resources.bank[pageid].img = {};
                        }
                        
                        var dlid = "dl_" + pageid + "_" + dltype + "_" + dls[d].getAttribute("id");
                        var dlname = dls[d].getElementsByTagName("dltxt")[0].firstChild.nodeValue;
                        var dlsrc = dls[d].getElementsByTagName("dlsrc")[0].firstChild.nodeValue;
                        
                        var dldescs = dls[d].getElementsByTagName("dldesc");
                        
                        oAltastic.resources.bank[pageid].img[dlid] = {
                            dlname : dlname,
                            dlsrc : dlsrc,
                            dldesc : [],
                            dlpreview : "images/previews/" + dlid + ".png"
                            
                        };
                        if (dls[d].getAttribute("onmainpage")) {
                            oAltastic.resources.bank[pageid].img[dlid].onmainpage = true;
                        }
                        var dlsizes = dls[d].getElementsByTagName("dlsizes");
                        if (dlsizes.length > 0) {
                            dlsizes = dlsizes[0].firstChild.nodeValue.split(",");
                            oAltastic.resources.bank[pageid].img[dlid].dlsizes = dlsizes;
                            
                            var dldefaultsize = dls[d].getElementsByTagName("dlsizes")[0].getAttribute("default");
                            oAltastic.resources.bank[pageid].img[dlid].defaultsize = dldefaultsize;
                        }
                        
                        for (var k = 0; k < dldescs.length; k++) {
                            oAltastic.resources.bank[pageid].img[dlid].dldesc[k] = dldescs[k].firstChild.nodeValue;
                        }
                        
                    }
                    else if (dltype == "document") {
                        
                        //if there is no subsection in the bank, make one
                        if (!oAltastic.resources.bank[pageid].dox) {
                            oAltastic.resources.bank[pageid].dox = {};
                        }
                        
                        var dlid = "dl_" + pageid + "_" + dltype + "_" + dls[d].getAttribute("id");
                        var dlname = dls[d].getElementsByTagName("dltxt")[0].firstChild.nodeValue;
                        var dlsrc = dls[d].getElementsByTagName("dlsrc")[0].firstChild.nodeValue;
                        
                        var dldescs = dls[d].getElementsByTagName("dldesc");
                        
                        oAltastic.resources.bank[pageid].dox[dlid] = {
                            dlname : dlname,
                            dlsrc : dlsrc,
                            dldesc : [],
                            dlpreview : "images/previews/" + dlid + ".png"
                            
                        };
                        if (dls[d].getAttribute("onmainpage")) {
                            oAltastic.resources.bank[pageid].dox[dlid].onmainpage = true;
                        }
                        for (var k = 0; k < dldescs.length; k++) {
                            oAltastic.resources.bank[pageid].dox[dlid].dldesc[k] = dldescs[k].firstChild.nodeValue;
                        }
                        
                    }
                    else if (dltype == "offliner") {
                        
                        //if there is no subsection in the bank, make one
                        if (!oAltastic.resources.bank[pageid].etc) {
                            oAltastic.resources.bank[pageid].etc = {};
                        }
                        
                        var dlid = "dl_" + pageid + "_" + dltype + "_" + dls[d].getAttribute("id");
                        var dlname = dls[d].getElementsByTagName("dltxt")[0].firstChild.nodeValue;
                        var dlsrc = dls[d].getElementsByTagName("dlsrc")[0].firstChild.nodeValue;
                        
                        var dldescs = dls[d].getElementsByTagName("dldesc");
                        
                        oAltastic.resources.bank[pageid].etc[dlid] = {
                            dlname : dlname,
                            dlsrc : dlsrc,
                            dldesc : [],
                            dlpreview : "images/previews/" + dlid + ".png"
                            
                        };
                        if (dls[d].getAttribute("onmainpage")) {
                            oAltastic.resources.bank[pageid].etc[dlid].onmainpage = true;
                        }
                        for (var k = 0; k < dldescs.length; k++) {
                            oAltastic.resources.bank[pageid].etc[dlid].dldesc[k] = dldescs[k].firstChild.nodeValue;
                        }
                        
                    }
                    
                }
                
            }
            oAltastic.xmlDoc = null;
            oAltastic.drawPage();
        },
        
        bank : {
            
        }
        
    },
    
    //the download button is disabled till we get confirmation from php that the file we want exists
    getSize : function (filename) {
        
        //clear the filesize div and inform the user of what we are doing
        var filesizediv = document.getElementById("res_filesize");
        $.purge(filesizediv);
        
        var filepathdiv = document.getElementById("res_filepath");
        $.purge(filepathdiv);
        
        //since it will take a second or so, make sure the dl button cannot be clicked, as it may be pointing to nothing
        document.getElementById("res_dl_btn").disableMe();
        
        filesizediv.appendChild($.makeSpan("<em>Getting download information; please wait....</em>", "filesize_span"));
        
        //set the action=ok (could be anything really) just so we know getfilesize.php is being called by the script, and not directly
        var args = "action=" + encodeURIComponent("ok") + "&fname=" + encodeURIComponent(filename);
        
        //now that we have our php query string...
        var xmlhttp = $.getXmlHttpRequestObject();
        
        //what to do when we receive confirmation the form has been processed
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                
                var filesize = xmlhttp.responseText;
                
                var filesizediv = document.getElementById("res_filesize");
                var filepathdiv = document.getElementById("res_filepath");
                
                if (filesizediv) {
                    $.purge(filesizediv);
                    filesizediv.appendChild($.makeSpan(filesize, "filesize_span"));
                    
                    $.purge(filepathdiv);
                    
                    //as long as the file seems to exist, enable the dl button, show the contents, and load the preview
                    if (filesize == "File not found.") {
                        document.getElementById("res_dl_btn").disableMe();
                        
                        filepathdiv.appendChild($.makeSpan("", "filepath_span"));
                        
                        //and kill the preview
                        document.getElementById("dl_preview").src = "images/previews/dl_none.png";
                    }
                    else {
                        document.getElementById("res_dl_btn").enableMe();
                        
                        filepathdiv.appendChild($.makeSpan("http://www.altastic.com/resources/" + document.getElementById("res_dl_btn").dlsrc.replace("[SIZE]", document.getElementById("res_dl_btn").dlsize), "filepath_span"));
                        
                    }
                    
                }
                
                
            }
        };
        
        //Send the proper header information along with the request
        
        xmlhttp.open("POST", "getfilesize.php", true);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(args);
        
    },
    
    /* GLOBALS */
    eCont : null,
    content : null,
    
    //contains the downloads information
    xmlDoc : null,
    
    browsers : {
        firefox : {
            fullname : "Mozilla Firefox",
            homepage : "http://www.mozilla.com/en-US/products/download.html"
        },
        opera : {
            fullname : "Opera",
            homepage : "http://www.opera.com/download/"
        },
        chrome : {
            fullname : "Google Chrome",
            homepage : "http://www.google.com/chrome/"
        },
        explorer : {
            fullname : "Microsoft Internet Explorer",
            homepage : "http://windows.microsoft.com/en-US/internet-explorer/products/ie/home"
        },
        safari : {
            fullname : "Apple Safari",
            homepage : "http://www.apple.com/safari/download/"
        }
    },
    
    /* draws the page onload - php does the header and footer; this inserts the menu and content pane, then populates the content pane */
    drawPage : function () {
        //get the cont
        oAltastic.eCont = $.tagMe("central");
        
        //the menu
        var eMenuDiv = oAltastic.eCont.appendChild($.makeDiv("menu"));
            //menu items - groups = m; sections = n
            for (var m in oAltastic.bank) {
                var eMenuGroup = eMenuDiv.appendChild($.makeDiv(m.replace("group_", ""), "menugroup"));
                
                for (var n in oAltastic.bank[m]) {
                    if ( (n == "groupName") || (n == "groupDescription") ) continue;
                    
                    var sectionid = n.replace("section_", "");
                    var sectionname = oAltastic.bank[m][n].sectionName;
                    
                    //anchor with an image and a span inside
                    var eMenuItem = $.makeAnchor("#" + sectionid, null, "menuitem", [$.makeImg("images/icons/" + sectionid + "_32.png", sectionname, null, "menuitem"), $.makeSpan(sectionname, null, "menuitem")]);
                    
                    eMenuGroup.appendChild($.makeDiv("menuitem_" + sectionid, "menuitem_blank", [eMenuItem]));
                }
                
            }
            
        
        //the content pane
        oAltastic.content = oAltastic.eCont.appendChild($.makeDiv("content"));
        
        
        
        //get and activate the search box
        var searchbox = $.tagMe("mainsearch_box");
            searchbox.onkeydown = function (e) {
                if (!e) var e = window.event;
                
                if (e.keyCode == 13) {
                    //update the hash
                    window.location.hash = this.value;
                    oAltastic.checkHash();
                }
            };
        
        //check if the user has a hash, and if so, get the appropriate page (or do a search for pages that match the term)
        oAltastic.checkHash();
        
        //if onhashchange is supported, use it
        /*DEV IE8-as-IE7 claims to have onhashchange because IE8 has it, but it is not implemented. therefore in IE7 mode, the setinterval is not called either, and no link does anything. so for dev, you need to disable the if and leave the setInterval on its own.*/
        if ("onhashchange" in window) {
            window.onhashchange = oAltastic.checkHash;
        }
        //for some browsers, onhashchange is not supported, so we set up a timer to check it ten times a second.
        else {
            setInterval(function () { oAltastic.checkHashOld() }, 100);
        }
        
        //and finally load the homepage, but only if there is no hash
        if (!window.location.hash) window.location.hash = "#home";
        
        
    },
    
    
    //gets the info a user entered in the contact form, checks it is valid, and submits it.
    //if anything is invalid we send nothing and inform the user.
    submitContactForm : function (el) {
        //check it was submitted by the submit button
        var sb = el.getAttribute("id");
        
        //get name
        var fname = encodeURIComponent($.tagMe("fname").value);
        if (!fname) fname = encodeURIComponent("-none-");
        
        //get email
        var email = $.tagMe("email").value;
        
        //check email validity
        if (email) {
            //modern email spec, not to mention IPv6, means that it is friggen impossible to make a catch-all. so just do this:
            if (email.indexOf("@") == -1) {
                $.tagMe("email_alert").innerHTML = "The format of the email address is invalid!";
                $.tagMe("email").onfocus = function () { $.tagMe("email_alert").innerHTML = ""; };
                return false;
            }
        }
        else {
            email = "-none-";
        }
        email = encodeURIComponent(email);
        
        //the type of comment
        var selector = $.tagMe("subject");
        var subject = encodeURIComponent(selector.options[selector.selectedIndex].text);
        
        //the actual comment itself
        var comment = encodeURIComponent($.tagMe("comment").value);
        if (!comment) {
            $.tagMe("comment_alert").innerHTML = "You must enter a comment!";
            $.tagMe("comment").onfocus = function () { $.tagMe("comment_alert").innerHTML = ""; };
            return false;
        }
        
        //uriencode all of the above, and concatenate them
        var args = "action=" + encodeURIComponent(sb) + "&fname=" + encodeURIComponent(fname) + "&email=" + encodeURIComponent(email) + "&subject=" + encodeURIComponent(subject) + "&comment=" + encodeURIComponent(comment);
        
        //now that we have our php query string...
        var xmlhttp = $.getXmlHttpRequestObject();
        
        //what to do when we receive confirmation the form has been processed
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                
                var msg = xmlhttp.responseText;
                var content = $.tagMe("section_content");
                $.purge(content);
                content.appendChild($.makeSpan(msg, "email_sent"));
                
            }
        };
        
        //Send the proper header information along with the request
        
        xmlhttp.open("POST", "contact.php", true);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(args);
        
        return true;
    },
    
    
    /* UTILITIES */
    
    //gets the hash, if any, and gets the appropriate content
    checkHash : function () {
        
        var newhash = window.location.hash;
        
        if (newhash) {
            try {
                newhash = newhash.replace("#", "");
                
                oAltastic.getContent(newhash);
                
                //set the menu
                var menudivs = document.getElementById("menu").getElementsByTagName("div");
                //cycle through the divs. make sure we are dealing with an inner div, not one of the group divs
                for (var i = 0; i < menudivs.length; i++) {
                    var thisid = menudivs[i].getAttribute("id");
                    if (/^menuitem_\w+/.test(thisid)) {
                        menudivs[i].className = "menuitem_blank";
                    }
                }
                
                var currentitem = $.tagMe("menuitem_" + newhash);
                if (currentitem) currentitem.className = "menuitem_selected";
                
            }
            catch (e) {
                //hash is not a valid link so do nothing
            }
        }
        
    },
    
    //gets the hash, if any, and throws it to ajaxify. irritating workaround for older browsers.
    oldhash : "#",
    checkHashOld : function () {
        
        var newhash = window.location.hash;
        
        if (newhash) {
            //check if it is the same as the last hash. if so quit now. if not, it's changed, so we update oldhash and call checkHash
            if (newhash == oAltastic.oldhash) return;
            
            else {
                oAltastic.oldhash = newhash;
                oAltastic.checkHash();
            }
        }
        
    },
    
    //makes the section header for all pages.
    makeSectionHeader : function (secid, secname, secdesc, secicon) {
        //an image, header and hr inside a div
        oAltastic.content.appendChild($.makeDiv(null, "section_header", [$.makeImg(secicon, secname + " icon", null, "section_header"), $.makeHdr(2, secname, null, "section_header_h"), secdesc, $.makeHR("section_header")]));
    },
    
    
    
    /* given a section name, this makes a section header and fills in the content. */
    getContent : function (query) {
        if (!query) return;
        
        $.purge(oAltastic.content);
        
        /* first we check to see if the word matches a given section id exactly */
        
        //cycle through the sections and see if there is a match.
        var currentSection = null;
        var currentSectionID = null;
        
        var breakout = false;
        
        for (var m in oAltastic.bank) {
            for (var n in oAltastic.bank[m]) {
                
                if ( (n == "groupName") || (n == "groupDescription") ) continue;
                
                var sect = n.replace("section_", "");
                
                if (sect == query) {
                    currentSection = oAltastic.bank[m][n];
                    currentSectionID = sect;
                    breakout = true;
                    break;
                }
            }
            if (breakout) break;
        }
        
        //for use later
        var pages = [];
        var pageids = [];
        
        //if we have a currentSection...
        if (currentSection) {
            //whether it is a mainpage or has subpages, it needs the same kind of header
            oAltastic.makeSectionHeader(currentSectionID, currentSection.sectionName, $.makeP(currentSection.sectionDescription), "images/icons/" + currentSectionID + "_100.png");
            
            /* if it is a section without any subpages, it will have a drawContent function */
            if (currentSection.drawContent) {
                currentSection.drawContent();
                return;
            }
            /* otherwise add the subpage objects to the pages array */
            else {
                for (var q in currentSection) {
                    if ( (q == "sectionName") || (q == "sectionDescription") ) continue;
                    
                    pages.push(currentSection[q]);
                    pageids.push(q);
                }
            }
            
            /* but if it does have subpages, we wanna list them. we also wanna list them if it is a search. since the mechanics are the same, we first get a list of subpages, be they in a section of the result of a search, and put them in an array. then we put the appropriate section header and list the subpages below it. */
        }
        else {
            //if the pages array is still empty, we try a tag search
            //run through the sections and if any match, add its pages
            
            for (var m in oAltastic.bank) {
                
                for (var n in oAltastic.bank[m]) {
                    if ( (n == "groupName") || (n == "groupDescription") ) continue;
                    
                    for (var o in oAltastic.bank[m][n]) {
                        if ( (o == "sectionName") || (o == "sectionDescription") ) continue;
                        
                        try {
                            var taglist = oAltastic.bank[m][n][o].pageTags;
                            
                            for (var r = 0; r < taglist.length; r++) {
                                if (query == taglist[r]) {
                                    pages.push(oAltastic.bank[m][n][o]);
                                    pageids.push(o);
                                    break;
                                }
                            }
                        }
                        catch (e) {
                            //there may be no page tags
                        }
                    }
                }
            }
            
            
            //get the number of results
            var hits = pages.length;
            var results = $.makeDiv(null, "section_header_description", [$.makeSpan(hits + " search result" + (hits == 1 ? "" : "s") + " for \"", "search_header_plain"), $.makeSpan(query, "search_header_bold"), $.makeSpan("\"" + (hits > 0 ? ":" : "."), "search_header_plain")]);
            
            oAltastic.makeSectionHeader("search", "Search", results, "images/icons/search_100.png");
            
        }
        
        /* now, assuming we haven't returned already, we have a list of pages */
        var sectpages = oAltastic.content.appendChild($.makeDiv("section_pages"));
        
        /************************/
        /* FILL IN THE SUBPAGES */
        /************************/
        //whether we have a specific section or a list of search results, the process is the same - list the subpages.
        
        if (pages.length == 0) {
            var nomatches = $.makeDiv(null, "search_nomatches");
                nomatches.appendChild($.makeSpan("No results found.", null, "search_nomatches"));
            
            sectpages.appendChild(nomatches);
        }
        else {
            for (var i = 0; i < pages.length; i++) {
                
                //the hr that splits the results from one another (don't need one at the very top)
                if (i > 0) sectpages.appendChild($.makeHR("section_pages_hr"));
                
                var pageid = pageids[i].replace("page_", "");
                
                //the div that contains all the info about a page
                var pagediv = $.makeDiv(pageid);
                
                //the name of the page and link thereto
                var headanchor = $.makeAnchor(pages[i].url, pageid + "_link", "page_link");
                    headanchor.appendChild($.makeHdr(3, pages[i].pageName, null, "page_header"));
                pagediv.appendChild(headanchor);
                
                //the preview image of the page
                var imganchor = $.makeAnchor(pages[i].url, pageid + "_link", "page_link_img");
                var imgcont = $.makeDiv(null, "page_preview imgdiv");
                    imganchor.appendChild($.makeImg("images/previews/" + pageid + ".png", pages[i].pageName + " preview", null, "page_preview"));
                    imgcont.appendChild(imganchor);
                pagediv.appendChild(imgcont);
                
                //the short description of the page
                var ptext = pages[i].shortDescription;
                var shortdesc = $.makeP(ptext, null, "page_shortdesc");
                pagediv.appendChild(shortdesc);
                
                //the long description - in css version, this is hidden unless the user wants to see it
                //longdescs can take more than one paragraph, so we cycle through them all
                var longdescs = pages[i].longDescription;
                for (var k = 0; k < longdescs.length; k++) {
                    var longdesc = $.makeP(longdescs[k], null, "vanish");
                        longdesc.altcss = "page_longdesc";
                    pagediv.appendChild(longdesc);
                }
                
                //the more... link to show the desc
                var morebtn = document.createElement("input");
                    morebtn.setAttribute("type", "button");
                    morebtn.className = "page_showlongdesc";
                    morebtn.value = "more　↓";
                    morebtn.onclick = function () {
                        var ps = this.parentNode.parentNode.getElementsByTagName("p");
                        for (var n = 0; n < ps.length; n++) {
                            if (ps[n].className == "vanish") {
                                ps[n].className = ps[n].altcss;
                                this.value = "less ↑";
                            }
                            else if (ps[n].className == ps[n].altcss) {
                                ps[n].className = "vanish";
                                this.value= "more ↓";
                            }
                        }
                    };
                    var div = $.makeDiv(null, "page_showlongdesc");
                        div.appendChild(morebtn);
                    
                pagediv.appendChild(div);
                
                //any caveats
                if (pages[i].caveatjava) {
                    pagediv.appendChild($.makeDiv(null, "caveat", [$.makeImg("images/icons/java_32.png", "", null, "caveat_icon"), $.makeSpan(pages[i].caveatjava, null, "caveat_span")]));
                }
                
                //any workswiths for lab items
                if (pages[i].workswith) {
                    for (var c in pages[i].workswith) {
                        pagediv.appendChild($.makeDiv(null, "workswith", [$.makeAnchor(oAltastic.browsers[c].homepage, null, "noborder", [$.makeImg("images/icons/" + c + "_32.png", "Download " + oAltastic.browsers[c].fullname, null, "workswith_icon")]), $.makeSpan(pages[i].workswith[c], null, "workswith_span")]));
                    }
                }
                
                
                //returns an array of dls for the subpages, or null if none exist
                var pageDownloads = oAltastic.resources.getPageDownloads(pageid);
                
                if (pageDownloads) {
                    
                    //make a container div for all the downloads and a header for it
                    //as long as there is a dl for a page, at least one will ALWAYS be onmainpage
                    var downloads = $.makeDiv(null, "page_downloads");
                        
                        //the button to toggle
                        var downloadsbtn = document.createElement("input");
                            downloadsbtn.setAttribute("type", "button");
                            downloadsbtn.className = "page_downloads_button";
                            downloadsbtn.value = "Downloads";
                            downloadsbtn.onclick = function () {
                                var dlsdiv = this.parentNode.getElementsByTagName("div")[0];
                                if (dlsdiv.className == "vanish") {
                                    dlsdiv.className = "page_downloads_box";
                                }
                                else {
                                    dlsdiv.className = "vanish";
                                }
                            };
                        downloads.appendChild(downloadsbtn);
                        
                        //and the div the button toggles
                        var downloadsbox = $.makeDiv(null, "vanish");
                            
                            //prepare a div for each of the three groups, but don't initialise it
                            var dldiv_images = null;
                            var dldiv_documents = null;
                            var dldiv_other = null;
                            
                            //cycle through the downloads
                            for (var k in pageDownloads) {
                                
                                if (k == "img") {
                                    
                                    for (var g in pageDownloads[k]) {
                                        if (!pageDownloads[k][g].onmainpage) continue;
                                        
                                        //if the div is not initialised, do it now
                                        if (!dldiv_images) {
                                            dldiv_images = $.makeDiv(null, "dltypediv");
                                            
                                            //the title part
                                            var dldiv_images_header = $.makeDiv(null, "dltypediv_header");
                                                dldiv_images_header.appendChild($.makeImg("images/icons/images_32.png", "", null, "dltypediv_header_img"));
                                                dldiv_images_header.appendChild($.makeHdr(4, "Images", null, "dltypediv_header_h"));
                                            dldiv_images.appendChild(dldiv_images_header);
                                            
                                            var dldiv_images_list = document.createElement("ul");
                                                dldiv_images_list.className = "page_downloads_list";
                                            dldiv_images.appendChild(dldiv_images_list);
                                            
                                        }
                                        
                                        var newli = document.createElement("li");
                                            //we only wanna replace the [SIZE] part if we actually have multiple sizes
                                            var aname = pageDownloads[k][g].dlsrc;
                                                if (pageDownloads[k][g].defaultsize) {
                                                    aname = aname.replace("[SIZE]", pageDownloads[k][g].defaultsize);
                                                }
                                            var newanchor = $.makeAnchor("resources/" + aname, null, "page_dl_anchor", pageDownloads[k][g].dlname);
                                            newli.appendChild(newanchor);
                                            
                                        dldiv_images_list.appendChild(newli);
                                    }
                                    
                                }
                                
                                else if (k == "dox") {
                                    
                                    for (var g in pageDownloads[k]) {
                                        if (!pageDownloads[k][g].onmainpage) continue;
                                        
                                        //if the div is not initialised, do it now
                                        if (!dldiv_documents) {
                                            dldiv_documents = $.makeDiv(null, "dltypediv");
                                            
                                            //the title part
                                            var dldiv_documents_header = $.makeDiv(null, "dltypediv_header");
                                                dldiv_documents_header.appendChild($.makeImg("images/icons/document_32.png", "", null, "dltypediv_header_img"));
                                                dldiv_documents_header.appendChild($.makeHdr(4, "Documents", null, "dltypediv_header_h"));
                                                dldiv_documents.appendChild(dldiv_documents_header);
                                            
                                            var dldiv_documents_list = document.createElement("ul");
                                                dldiv_documents_list.className = "page_downloads_list";
                                                dldiv_documents.appendChild(dldiv_documents_list);
                                                
                                        }
                                        
                                        var newli = document.createElement("li");
                                            newli.appendChild($.makeAnchor("resources/" + pageDownloads[k][g].dlsrc, null, "page_dl_anchor", pageDownloads[k][g].dlname));
                                            
                                        dldiv_documents_list.appendChild(newli);
                                    }
                                }
                                
                                else if (k == "etc") {
                                    
                                    for (var g in pageDownloads[k]) {
                                        if (!pageDownloads[k][g].onmainpage) continue;
                                            
                                        //if the div is not initialised, do it now
                                        if (!dldiv_other) {
                                            dldiv_other = $.makeDiv(null, "dltypediv");
                                            
                                            //the title part
                                            var dldiv_other_header = $.makeDiv(null, "dltypediv_header");
                                                dldiv_other_header.appendChild($.makeImg("images/icons/miscdownloads_32.png", "", null, "dltypediv_header_img"));
                                                dldiv_other_header.appendChild($.makeHdr(4, "Miscellaneous", null, "dltypediv_header_h"));
                                            dldiv_other.appendChild(dldiv_other_header);
                                                
                                            var dldiv_other_list = document.createElement("ul");
                                                dldiv_other_list.className = "page_downloads_list";
                                            dldiv_other.appendChild(dldiv_other_list);
                                            
                                        }
                                        
                                        var newli = document.createElement("li");
                                            newli.appendChild($.makeAnchor("resources/" + pageDownloads[k][g].dlsrc, null, "page_dl_anchor", pageDownloads[k][g].dlname));
                                            
                                        dldiv_other_list.appendChild(newli);
                                    }
                                }
                            
                            }
                            
                            if (dldiv_images) downloadsbox.appendChild(dldiv_images);
                            if (dldiv_documents) downloadsbox.appendChild(dldiv_documents);
                            if (dldiv_other) downloadsbox.appendChild(dldiv_other);
                            
                            //the "more dls are available" bit
                            var moredl = $.makeDiv(null, "page_downloads_more");
                                moredl.appendChild($.makeSpan("Check out the&nbsp;", null, "page_downloads_more_span"));
                                var moredlanchor = $.makeAnchor("#resources", null, "page_downloads_more_a", "resources page");
                                moredl.appendChild(moredlanchor);
                                moredl.appendChild($.makeSpan("&nbsp;for more downloads.", null, "page_downloads_more_span"));
                            downloadsbox.appendChild(moredl);
                            
                        downloads.appendChild(downloadsbox);
                        
                    pagediv.appendChild(downloads);
                    
                }
                
                sectpages.appendChild(pagediv);
            }
        }
        
        oAltastic.content.appendChild(sectpages);
        
    },
    
    
    /* contains all content used on the index pages */
    bank : {
        /* sections are grouped roughly according to similarities */
        group_ict : {
            groupName : "ICT",
            groupDescription : "Stuff for use on an interactive whiteboard",
            
            /* sections are what we call menu items. they appear to be subpages of index.php, and appear right of the menu */
            section_flashcards : {
                sectionName : "Flashcards",
                sectionDescription : "Various flashcard sets for use on an interactive whiteboard.",
                
                /* most sections are simply a list of "pages", which are explanations of and links to actual altastic.com pages */
                page_abc : {
                    pageName : "ABC",
                    url : "abc",
                    shortDescription : "Flashcards for practicing the letters of the alphabet.",
                    longDescription : ["The letter designs are based upon the Zaner-Bloser-style fonts that most school textbooks in Japan use.", "Movement is controlled by the left and right buttons. By default, the letters are in order from A to Z, but you can randomize them if you like.", "Both upper- and lowercase are included, as well as both block and cursive handwriting styles, and you can toggle the guidelines.", "All buttons also have keyboard shortcuts, which you can read about in detail by clicking the Help button on the page itself."],
                    
                    pageTags : ["abc", "alphabet", "flashcard", "flashcards", "_"]
                    
                },
                
                page_abccolor : {
                    pageName : "ABC Colo(u)r",
                    url : "abccolor",
                    shortDescription : "Colorful flashcards for practicing the letters of the alphabet.",
                    longDescription : ["The letters are in an easily-readable font, in bright colo(u)rs. Each letter comes with plain and picture versions. The pictures are of simple items that begin with the corresponding letter - apple for A, bag for B, and so on. Some letters have more than one accompanying picture you can choose from.", "Movement can be controlled by the arrows on the page. There are also buttons for toggling between plain and picture versions. By default the letters go from A to Z in order, but you can randomize their order if you want to. You can also jump to any letter at any time by typing it on your keyboard. In fact, there is a keyboard shortcut for everything; for more information, click the Help button on the page itself."],
                    
                    pageTags : ["abc", "abccolor", "abccolour", "abc color", "abc colour", "alphabet", "flashcard", "flashcards", "_"]
                    
                },
                
                page_numbers : {
                    pageName : "Numbers",
                    url : "numbers",
                    shortDescription : "Flashcards for practicing numbers.",
                    longDescription : ["You can make a slideshow of any set of numbers from 0 to 99,999. Both digits and words can be toggled on or off."],
                    
                    pageTags : ["num", "number", "numbers", "123", "flashcard", "flashcards", "_"]
                    
                },
                
                page_whatsthis : {
                    pageName : "What's This",
                    url : "whatsthis",
                    shortDescription : "Mystery image flashcards.",
                    longDescription : ["A peculiar image is displayed along with a question, and the students have to guess what it is. The answer image and text are then revealed.", "You can change the form of the question and answer, and choose which images you want to use."],
                    
                    pageTags : ["mystery", "that", "this", "what", "what's", "whats", "wtf,", "what's this?", "flashcard", "flashcards", "_"]
                    
                },
                
                page_flags : {
                    pageName : "Flags of the World",
                    url : "flags",
                    shortDescription : "Flashcards of most of the flags of the world.",
                    longDescription : ["You can easily and quickly select the flags you want using the simple search tool. You can also choose some optional text ('What's this?' and 'It's Cameroon!', etc.).", "I believe most countries are represented, but <a href='#contact'>let me know</a> if there's one missing that you'd like to see included."],
                    
                    pageTags : ["country", "countries", "flag", "flags", "flags of the world", "world", "flashcard", "flashcards", "_"]
                    
                },
                
                page_verbinator : {
                    pageName : "The Verbinator",
                    url : "verbinator",
                    shortDescription : "A list of the bare infinitive, past and present tense, and Japanese meaning of the most common English irregular verbs.",
                    longDescription : ["You can choose which verbs to display, and the order in which they appear. You can also switch on-the-fly between two display modes.", "In List mode, several verbs are shown in a list, and you can blank out individual items (hopefully useful for drilling).", "In Flashcard mode, you can see one verb at a time, and move through the list in a simple slideshow.", "In either mode, each part of speech (including the Japanese meaning) can be toggled on or off."],
                    
                    pageTags : ["verb", "verbs", "irregular", "verbinator", "flashcard", "flashcards", "_"]
                    
                }
                
                ,
                
                page_convo : {
                    pageName : "Convo",
                    url : "convo",
                    shortDescription : "Various flashcards for practicing simple conversational expressions.",
                    longDescription : ["There are four main categories: <i>requesting</i>, <i>offering</i>, <i>invitation</i> and <i>permission</i>, each with two skits to illustrate the usage of the grammar."],
                    
                    pageTags : ["conversation", "chat", "talk", "speak", "flashcard", "flashcards", "_"]
                    
                },
                
                page_shade : {
                    pageName : "Shade",
                    url : "shade",
                    shortDescription : "A flashcard viewer with the added bonus of a shade to hide part of the image.",
                    longDescription : ["You can choose from various flashcards and display them on the interactive whiteboard. You can also choose to hide them with shades, for 'What's this?'-style activities.", "There are five types of shade, selectable by the buttons down the side. For various reasons, browser zooming is not supported on this page. I'm working on a way to fix this."],
                    
                    pageTags : ["shade", "flashcard", "flashcards", "hide", "sports", "food", "fruit", "music", "_"]
                    
                }
                
                /*,
                
                page_XXX : {
                    pageName : "",
                    url : "",
                    shortDescription : "",
                    longDescription : [""],
                    
                    pageTags : ["", "_"]
                    
                }
                */
                
            },
            
            
            section_scorers : {
                sectionName : "Scorers",
                sectionDescription : "Various scorekeepers for use on an interactive whiteboard.",
                
                page_wackie : {
                    pageName : "Wackie Races",
                    url : "wackieraces",
                    shortDescription : "An easy way to track the progress of several groups as they answer questions.",
                    longDescription : ["If you want students to answer a bunch of questions in order, this offers a much more interesting and colorful way to keep track of each team's progress.", "This is basically a jazzed-up version of Not Particularly Wacky Races."],
                    
                    pageTags : ["wackie", "wackie races", "wacky", "wacky races", "race", "races", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_scoreboard : {
                    pageName : "Scoreboard",
                    url : "scoreboard",
                    shortDescription : "A simple scoreboard.",
                    longDescription : ["You can select one of five themes. Team mascots will be assigned at random, and you can assign points to each team easily using the plus and minus buttons. You can also drag the team icons around the screen, to simulate the layout of the classroom floor.", "Unfortunately, browser zooming is not supported at the moment. I am working on a way to fix this."],
                    
                    pageTags : ["scoreboard", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_gamblor : {
                    pageName : "Gamblor",
                    url : "gamblor",
                    shortDescription : "A scoreboard for gambling.",
                    longDescription : ["If you're anything like me, you'll want to introduce your students to aspects of culture they may not be familiar with, in order to fully prepare them for the real world. I think it is also important to infuse them with a sense of morality and fair play. To that end, I often teach them to gamble. If you have ever tried a gambling activity but given up because it was too hard to keep score, this will help you keep track of the scores more easily. What it lacks in style it makes up for in... er... arithmetic."],
                    
                    pageTags : ["gamble", "gambling", "gamblor", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_scoreline : {
                    pageName : "Scoreline",
                    url : "scoreline",
                    shortDescription : "A very simple scoreboard to keep track of questions answered.",
                    longDescription : ["If you have a bunch of questions you want students to answer in any order, this is a simple but fun way to keep track of which team's done what."],
                    
                    pageTags : ["scoreline", "numbers", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_npwr : {
                    pageName : "Not Particularly Wacky Races",
                    url : "npwr",
                    shortDescription : "An easy way to track the progress of several groups as they answer questions.",
                    longDescription : ["If you want students to answer a bunch of questions in order, this offers an interesting and colorful way to keep track of each team's progress.", "While I originally intended to use all sorts of wacky vehicles, the only images I could find that were free were, despite undoubtedly being the product of hours of painstaking work on the part of the authors, nevertheless tragically boring. For this, I apologise in advance. If I ever develop any artistic skill, I'll be sure to come up with more interesting ones."],
                    
                    pageTags : ["wacky", "wacky races", "not particularly wacky races", "race", "races", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_attack : {
                    pageName : "Attack",
                    url : "attack",
                    shortDescription : "A slightly more interesting way to keep score. Basically Othello/Reversi with multiple teams.",
                    longDescription : ["Teams compete to conquer the board. If a team surrounds another token with two of its own, it takes the square(s) in between.", "Team mascots are assigned randomly, and you can change the team names if you like."],
                    
                    pageTags : ["attack", "othello", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                },
                
                page_xmastic : {
                    pageName : "Christmastic",
                    url : "xmastic",
                    shortDescription : "A colorful scoreboard for the yuletide season.",
                    longDescription : ["Place ornaments on a tree or presents under it to represent points gained. Each team is assigned a different type of bauble, and you can change the team names if you like. Great for injecting a little Christmas into the classroom."],
                    
                    pageTags : ["christmas", "xmas", "christmastic", "xmastic", "score", "scorer", "scorers", "scoreboard", "_"]
                    
                }/*,
                
                page_jeopardy : {
                    pageName : "Jeopardy",
                    url : "Jeopardy",
                    shortDescription : "A customizable scoreboard for when you play Jeopardy.",
                    longDescription : ["Choose the number of questions and categories, the points, and keep score."],
                    
                    pageTags : ["", "_"]
                    
                }*/
                
                
            },
            
            
            section_interactive : {
                sectionName : "Interactive Stuff",
                sectionDescription : "Various fun activities for use on an interactive whiteboard. More interactive than mere flashcards, but less interactive than... well, actual reality.",
                
                page_clock : {
                    pageName : "Clock",
                    url : "clock",
                    shortDescription : "An interactive clock.",
                    longDescription : ["The time is displayed in four ways - an analog clock, a digital clock, in text, and a representative image of the sky in the background. Hopefully it will help make teaching the time more interesting."],
                    caveatjava : "Requires Java 6",
                    
                    pageTags : ["clock", "time", "_"]
                    
                },
                /*
                page_tiles : {
                    pageName : "Tiles",
                    url : "tiles",
                    shortDescription : "A set of alphabet tiles you can move around the screen.",
                    longDescription : ["Hopefully useful when teaching the alphabet. You can rearrange the letters so they are in order, spell out various words, switch between lower- and uppercase, and much much more! Or, well, nothing more, actually. Unfortunately browser zoom is not supported on this page at the moment. Please bear with me while I work on a way to fix it."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_howmany : {
                    pageName : "How Many?",
                    url : "howmany",
                    shortDescription : "A tool to help get students to say numbers out loud, and to practice plural forms of nouns.",
                    longDescription : ["Choose from a set of common vocabulary words, and the page will generate a random number of images for each word."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_elements : {
                    pageName : "Elements",
                    url : "elements",
                    shortDescription : "An interactive periodic table.",
                    longDescription : ["Interactive information about each and every element that has been discovered. Caveat: I am not a scientist. I just chose to make a periodic table because I think it's a beautiful thing. <a href="#contact">Let me know</a> if anything is amiss."],
                    
                    pageTags : ["", "_"]
                    
                },
                */
                page_dice : {
                    pageName : "Dice",
                    url : "dice",
                    shortDescription : "More or less does what you'd expect.",
                    longDescription : ["An interactive set of virtual dice. You can add more dice at the tap of a button. Click on a die to roll it, and click the 'Roll all' button to roll them all. You can choose to show or hide the total."],
                    
                    pageTags : ["dice", "die", "random", "number", "numbers", "_"]
                    
                }/*,
                
                page_countdown : {
                    pageName : "Countdown",
                    url : "countdown",
                    shortDescription : "A timer that counts down from a specified time.",
                    longDescription : ["That's... about it.", "Since that would be rather (read: incredibly) dull, you can choose from one of several timer styles to jazz things up a bit."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_randomizer : {
                    pageName : "Randomizer",
                    url : "randomizer",
                    shortDescription : "A random number generator.",
                    longDescription : ["Generate a random number between any given range. Allow or disable repeats as you wish.", "I designed this for situations when I needed to call on a random student. All students have an ID number between 1 and about 40, and this was a more exciting way to do it than my old method (chopsticks with numbers written on them)."],
                    
                    pageTags : ["", "_"]
                    
                }
                */
                
            }
            
            
        },
        
        group_prep : {
            groupName : "Prep",
            groupDescription : "Stuff (mostly) designed for class preparation",
            
            section_utilities : {
                sectionName : "Utilities",
                sectionDescription : "Various utilities you can use sitting behind your desk.",
                
                page_nhsearch : {
                    pageName : "New Horizon Vocabulary Search",
                    url : "newhorizon/vocabsearch",
                    shortDescription : "Search the words in the New Horizon textbooks.",
                    longDescription : ["If you're not sure whether students have studied a particular word yet, search for it here to find out where the word first appears. You can also narrow the search by part of speech."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_nhlist : {
                    pageName : "New Horizon Vocabulary List",
                    url : "newhorizon/vocablist",
                    shortDescription : "List words from a given page or chapter in the New Horizon books.",
                    longDescription : ["Search by page number or by chapter number. You can also narrow the search by part of speech."],
                    
                    pageTags : ["", "_"]
                    
                },
                /*
                page_nhpractice : {
                    pageName : "New Horizon Vocabulary Practice",
                    url : "newhorizon/vocabpractice",
                    shortDescription : "A word practice worksheet generator for the New Horizon textbooks.",
                    longDescription : ["Choose a page in one of the textbooks and get a PDF version of a worksheet for students to practice writing the words."],
                    
                    pageTags : ["", "_"]
                    
                },
                */
                page_scramblinator : {
                    pageName : "Scramblinator",
                    url : "scramblinator",
                    shortDescription : "A tool to quickly scramble the words and/or letters in a given sentence. Much less hassle than doing it by hand.",
                    longDescription : ["Select whether you want to scramble words or characters, or both. You can choose what, if any, character to use to separate the words, and you can choose to remove any errant punctuation."],
                    
                    pageTags : ["", "_"]
                    
                },
                /*
                page_dateabase : {
                    pageName : "Dateabase",
                    url : "dateabase",
                    shortDescription : "A database of public holidays in many countries.",
                    longDescription : ["By no means perfect, or particularly useful. Just a way to see which country celebrates which public holidays when. There are almost certainly mistakes; <a href='#contact'>let me know</a> if you find any. Certain non-static festivals, usually based on the lunar cycle, do not have reliable dates, so they may be missing; sorry about that."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_myojinator : {
                    pageName : "Myojinator",
                    url : "myojinator",
                    shortDescription : "A tool to generate English versions of common Japanese names.",
                    longDescription : ["I have endeavoured to include all the name kanji I know of, but there are bound to be some missing. Do <a href="#contact">let me know</a> if there are any I have missed, or if you have a better translation."],
                    
                    pageTags : ["", "_"]
                    
                },
                */
                page_wordify : {
                    pageName : "Wordify",
                    url : "wordify",
                    shortDescription : "Enter a number in digits and see it converted to words.",
                    longDescription : ["Should work for any number you have a use for, though what on earth you'd need it for (besides idle curiosity) I can't imagine. It's more of a programming exercise than anything else. There are technical limitations beyond about a vigintillion (yeah, it's a real number)."],
                    
                    pageTags : ["", "_"]
                    
                },
                /*
                page_colorizer : {
                    pageName : "The Colorizer",
                    url : "colorizer",
                    shortDescription : "Convert to and from hex, RGB and HTML color names.",
                    longDescription : ["A tool more suited for web designers than English teachers, but what they heck, says I."],
                    
                    pageTags : ["", "_"]
                    
                },
                */
                page_regexinator : {
                    pageName : "RegExinator",
                    url : "regexinator",
                    shortDescription : "A tool for testing regular expressions in Javascript.",
                    longDescription : ["Enter a regular expression and a string to test whether the expression is valid. Meant for web designers, obviously, not English teachers."],
                    
                    pageTags : ["", "_"]
                    
                }/*,
                
                page_convertinator : {
                    pageName : "The Convertinator",
                    url : "convertinator",
                    shortDescription : "Converts almost any measurement to almost any other.",
                    longDescription : ["Okay, so that is a slight exaggeration. It converts the things I could find a decent conversion factor for. It's as accurate as I could make it proofreading the results myself. As always, I ask you to <a href='#contact'>tell me</a> if you find any mistakes."],
                    
                    pageTags : ["", "_"]
                    
                }
                */
                
            },
            
            section_resources : {
                sectionName : "Resources",
                sectionDescription : "Downloadable versions of some pages, downloadable image sets, and other useful documents, all free.",
                
                /* since Resources does not contain pages, oAltastic will try to call the drawContent method, which should be available for all the sections without subpages (home, contact, faq, about, and resources) */
                
                drawContent : function () {
                    
                    //make the lower part of the content - sectionContent
                    var sectionContent = $.makeDiv("section_content");
                        
                        //make the upper div, which never changes
                        var resUpperDiv = $.makeDiv("res_upper_div");
                            
                            //explanation of what's what
                            resUpperDiv.appendChild($.makeP("Everything here is free to download, but some images and other documents have usage restrictions. You can find out more on the <a href='#about'>about page</a>. Enjoy!", null, "smallp"));
                            
                            //draw the main dd
                            var resMainDD = document.createElement("select");
                                resMainDD.setAttribute("id", "res_main_selector");
                                resMainDD.className = "resources_select";
                                var baseopt = document.createElement("option");
                                    basetxt = "- Select a download category -";
                                    baseopt.innerHTML = basetxt;
                                    baseopt.setAttribute("text", basetxt);
                                    baseopt.setAttribute("label", basetxt);
                                    baseopt.className = "resources_opts";
                                resMainDD.appendChild(baseopt);
                                
                                var usedsections = "#";
                                
                                for (var m in oAltastic.resources.bank) {
                                    var thissection = oAltastic.bank[oAltastic.resources.bank[m].groupid][oAltastic.resources.bank[m].sectid].sectionName;
                                    
                                    //only add a new section of the same name if we don't have one already
                                    if (usedsections.indexOf("#" + thissection + "#") == -1) {
                                        
                                        var newoptgp = document.createElement("optgroup");
                                            newoptgp.setAttribute("label", thissection);
                                            newoptgp.className = "resources_opts";
                                            
                                            usedsections += thissection;
                                            usedsections += "#";
                                        
                                        resMainDD.appendChild(newoptgp);
                                        
                                    }
                                    
                                    //if m is "dox" it has no pageName so we deal with it separately
                                    try {
                                        var optxt = oAltastic.bank[oAltastic.resources.bank[m].groupid][oAltastic.resources.bank[m].sectid]["page_" + m].pageName;
                                    }
                                    catch (e) {
                                        optxt = "Documents, Printables & Guides";
                                    }
                                    
                                    //add the options to the optgroup
                                    var newopt = document.createElement("option");
                                        newopt.innerHTML = optxt;
                                        newopt.setAttribute("text", optxt);
                                        newopt.setAttribute("label", optxt);
                                        newopt.className = "resources_opts";
                                        newopt.sectid = oAltastic.resources.bank[m].sectid;
                                        newopt.pageid = m;
                                    newoptgp.appendChild(newopt);
                                    
                                }
                                
                                //the onchange
                                resMainDD.onchange = function () {
                                    //kill the lower div if it exists
                                    try {
                                        var reslower = document.getElementById("res_lower_div");
                                            reslower.parentNode.removeChild(reslower);
                                    }
                                    catch (e) {
                                        
                                    }
                                    
                                    //if we are on the first option, we don't wanna do anything
                                    if (this.selectedIndex == 0) return;
                                    
                                    //get the section and id of the current selection
                                    var sectid = this.options[this.selectedIndex].sectid;
                                    var pageid = this.options[this.selectedIndex].pageid;
                                    
                                    //make the lower div, which changes according to the main dd selection
                                    var resLowerDiv = $.makeDiv("res_lower_div");
                                        
                                        //the top part of the lower div, which contains only the subdd
                                        var resLowerTopDiv = $.makeDiv("res_lower_top_div");
                                                                        
                                            //make a dd to list the dls for this section
                                            var resSubDD = document.createElement("select");
                                                resSubDD.setAttribute("id", "res_sub_selector");
                                                resSubDD.className = "resources_select";
                                                
                                                var baseopt = document.createElement("option");
                                                    basetxt = "- Select a download -";
                                                    baseopt.innerHTML = basetxt;
                                                    baseopt.setAttribute("text", basetxt);
                                                    baseopt.setAttribute("label", basetxt);
                                                    baseopt.className = "resources_opts";
                                                resSubDD.appendChild(baseopt);
                                                
                                                //first make dl type optgroups
                                                for (var t in oAltastic.resources.bank[pageid]) {
                                                    if ( (t == "groupid") || (t == "sectid") ) continue;
                                                    
                                                    var newoptgp = document.createElement("optgroup");
                                                        newoptgp.setAttribute("label", oAltastic.resources.acronyms[t]);
                                                        newoptgp.className = "resources_opts";
                                                        
                                                    //then list the dls themselves
                                                    for (var d in oAltastic.resources.bank[pageid][t]) {
                                                        var newopt = document.createElement("option");
                                                            var optxt = oAltastic.resources.bank[pageid][t][d].dlname;
                                                            newopt.innerHTML = optxt;
                                                            newopt.setAttribute("text", optxt);
                                                            newopt.setAttribute("label", optxt);
                                                            newopt.className = "resources_opts";
                                                            newopt.dltype = t;
                                                            newopt.dlid = d;
                                                        newoptgp.appendChild(newopt);
                                                    }
                                                    
                                                    resSubDD.appendChild(newoptgp);
                                                }
                                                
                                                //create the lower part of the bottom div and populate it with 3 divs
                                                resSubDD.onchange = function () {
                                                    //kill the lower bottom div if it exists already
                                                    try {
                                                        var reslower = document.getElementById("res_lower_bottom_div");
                                                            reslower.parentNode.removeChild(reslower);
                                                    }
                                                    catch (e) {
                                                        
                                                    }
                                                    //if we are on the first option, we don't wanna do anything
                                                    if (this.selectedIndex == 0) return;
                                                    
                                                    //get the sectid and pageid, along with the currently selected dl id
                                                    maindd = document.getElementById("res_main_selector");
                                                    var sectid = maindd.options[maindd.selectedIndex].sectid;
                                                    var pageid = maindd.options[maindd.selectedIndex].pageid;
                                                    
                                                    var dltype = this.options[this.selectedIndex].dltype;
                                                    var dlid = this.options[this.selectedIndex].dlid;
                                                    
                                                    //the bottom part of the lower div, which contains 3 divs which change with the subdd
                                                    var resLowerBottomDiv = $.makeDiv("res_lower_bottom_div");
                                                        
                                                        //an expl div, with one or more ps
                                                        var resExplDiv = $.makeDiv("res_expl_div");
                                                        
                                                            var imgcont = $.makeDiv(null, "res_img_preview imgdiv");
                                                                imgcont.appendChild($.makeImg(oAltastic.resources.bank[pageid][dltype][dlid].dlpreview, oAltastic.resources.bank[pageid][dltype][dlid].dlname, "dl_preview", "res_img_preview"));
                                                            resExplDiv.appendChild(imgcont);
                                                            
                                                            for (var i = 0; i < oAltastic.resources.bank[pageid][dltype][dlid].dldesc.length; i++) {
                                                                resExplDiv.appendChild($.makeP(oAltastic.resources.bank[pageid][dltype][dlid].dldesc[i], null, "res_p_expl"));
                                                            }
                                                        resLowerBottomDiv.appendChild(resExplDiv);
                                                        
                                                        //an options div, with at least a dl button, and in some cases other inputs (for size, etc)
                                                        var resOptsDiv = $.makeDiv("res_opts_div");
                                                            if (oAltastic.resources.bank[pageid][dltype][dlid].dlsizes) {
                                                                //we wanna know which index matches the default size so we can set the dd to that when we add it to the document
                                                                var indexToSelect = 0;
                                                                
                                                                //make a label for it
                                                                var imgSizeLabel = document.createElement("label");
                                                                    imgSizeLabel.htmlFor = "imgsize_dd";
                                                                    imgSizeLabel.innerHTML = "<strong>Image size: </strong>";
                                                                resOptsDiv.appendChild(imgSizeLabel);
                                                                
                                                                var imgSizeDD = document.createElement("select");
                                                                    imgSizeDD.setAttribute("id", "imgsize_dd");
                                                                    imgSizeDD.className = "resources_select";
                                                                    
                                                                    for (var k = 0; k < oAltastic.resources.bank[pageid][dltype][dlid].dlsizes.length; k++) {
                                                                        var newopt = document.createElement("option");
                                                                            var optxt = oAltastic.resources.bank[pageid][dltype][dlid].dlsizes[k];
                                                                            newopt.innerHTML = optxt;
                                                                            newopt.setAttribute("text", optxt);
                                                                            newopt.setAttribute("label", optxt);
                                                                            newopt.className = "resources_opts";
                                                                            
                                                                            if (optxt == oAltastic.resources.bank[pageid][dltype][dlid].defaultsize) {
                                                                                indexToSelect = k;
                                                                            }
                                                                            
                                                                        imgSizeDD.appendChild(newopt);
                                                                    }
                                                                    imgSizeDD.onchange = function () {
                                                                        document.getElementById("res_dl_btn").dlsize = this.options[this.selectedIndex].text;
                                                                        
                                                                        oAltastic.getSize(document.getElementById("res_dl_btn").dlsrc.replace("[SIZE]", document.getElementById("res_dl_btn").dlsize));
                                                                    };
                                                                resOptsDiv.appendChild(imgSizeDD);
                                                                imgSizeDD.selectedIndex = indexToSelect;
                                                            }
                                                            
                                                            var resFileSize = $.makeDiv(null, "res_filesize");
                                                                resFileSize.setAttribute("id", "res_filesize");
                                                                resFileSize.innerHTML = "";
                                                            resOptsDiv.appendChild(resFileSize);
                                                            
                                                            var resFilePath = $.makeDiv(null, "res_filepath");
                                                                resFilePath.setAttribute("id", "res_filepath");
                                                                resFilePath.innerHTML = "";
                                                            resOptsDiv.appendChild(resFilePath);
                                                            
                                                            var resDlBtn = document.createElement("input");
                                                                resDlBtn.setAttribute("type", "button");
                                                                resDlBtn.setAttribute("id", "res_dl_btn");
                                                                resDlBtn.value = "Download";
                                                                resDlBtn.disabled = true;
                                                                resDlBtn.className = "res_dl_btn_dead";
                                                                resDlBtn.enableMe = function () {
                                                                    this.disabled = false;
                                                                    this.className = "res_dl_btn_alive";
                                                                };
                                                                resDlBtn.disableMe = function () {
                                                                    this.disabled = true;
                                                                    this.className = "res_dl_btn_dead";
                                                                };
                                                                resDlBtn.dlsrc = oAltastic.resources.bank[pageid][dltype][dlid].dlsrc;
                                                                //if this is an image, there may be a default size. we use this to replace [SIZE] in the path. if it is not an image we will just use a blank string
                                                                resDlBtn.dlsize = oAltastic.resources.bank[pageid][dltype][dlid].defaultsize ? oAltastic.resources.bank[pageid][dltype][dlid].defaultsize : "";
                                                                resDlBtn.onclick = function () {
                                                                    var dlsource = this.dlsrc.replace("[SIZE]", this.dlsize);
                                                                    
                                                                    window.location = "resources/" + dlsource;
                                                                    
                                                                };
                                                            resOptsDiv.appendChild(resDlBtn);
                                                        resLowerBottomDiv.appendChild(resOptsDiv);
                                                        
                                                    document.getElementById("res_lower_div").appendChild(resLowerBottomDiv);
                                                    
                                                    //finally update the current file size, if any
                                                    oAltastic.getSize(document.getElementById("res_dl_btn").dlsrc.replace("[SIZE]", document.getElementById("res_dl_btn").dlsize));
                                                    
                                                };
                                            
                                            resLowerTopDiv.appendChild(resSubDD);
                                            
                                        resLowerDiv.appendChild(resLowerTopDiv);    
                                        
                                    document.getElementById("section_content").appendChild(resLowerDiv);
                                    
                                };
                                
                            resUpperDiv.appendChild(resMainDD);    
                            
                        sectionContent.appendChild(resUpperDiv);
                    
                    oAltastic.content.appendChild(sectionContent);
                    
                }
                
            }
            
            
        },
        
        group_fun : {
            groupName : "Fun stuff",
            groupDescription : "Stuff that's fun (and possibly educational).",
            
            section_timekillers : {
                sectionName : "Timekillers",
                sectionDescription : "Things to do when you find yourself without sufficient work to occupy your time.",
                
                page_nations : {
                    pageName : "The Nations Quiz",
                    url : "nations",
                    shortDescription : "A quiz about flags, capitals and country names.",
                    longDescription : ["Think you're fairly international? See how much you really know."],
                    caveatjava : "Requires Java 6",
                    
                    pageTags : ["nations", "countries", "country", "game", "games", "timekiller", "timekillers", "_"]
                    
                },
                
                page_hangwords : {
                    pageName : "Hangwords",
                    url : "hangwords",
                    shortDescription : "Guess the word by choosing letters.",
                    longDescription : ["There are a couple of lifelines you can use, and the hangman image sets can be changed. The words you have to guess range from fairly simple to downright bizarre...."],
                    
                    pageTags : ["words", "hangman", "hangwords", "game", "games", "timekiller", "timekillers", "_"]
                    
                },
                
                page_jigsaw : {
                    pageName : "Jigsaw",
                    url : "jigsaw",
                    shortDescription : "A jigsaw puzzle.",
                    longDescription : ["If you require more explanation than that, perhaps you are not yet ready for jigsaws.", "Unfortunately, browser zoom is not supported at the moment. Please bear with me while I try to find a solution."],
                    
                    pageTags : ["jigsaw", "puzzle", "game", "games", "timekiller", "timekillers", "_"]
                    
                }/*,
                
                page_memory : {
                    pageName : "Memory",
                    url : "memory",
                    shortDescription : "Try to remember where all the cards are, and pair them all off.",
                    longDescription : ["There are several sets to choose from, including some "educational" ones involving English and Japanese words."],
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_reversify : {
                    pageName : "Reversify",
                    url : "reversify",
                    shortDescription : "A game very similar to what most refer to by the name of a Shakespeare play.",
                    longDescription : ["Reversi, except that it doesn't always work properly. I'm trying to fix the bugs, so bear me. Incidentally, the AI has only three command statements. It should be fairly easy to beat it even for a beginner. What can I say, I'm not a game theorist."],
                    
                    pageTags : ["", "_"]
                    
                }
                */
                
            },
            
            section_lab : {
                sectionName : "The Lab",
                sectionDescription : "Pages using newer technologies such as SVG, which are not supported in all browsers (but which are too cool not to make use of).",
                
                page_penmanship : {
                    pageName : "Penmanship",
                    url : "penmanship/penmanship.svg",
                    shortDescription : "See how to correctly write the letters of the English alphabet.",
                    longDescription : ["Choose between basic, block and cursive styles, show or hide guidelines, and all the letters can be animated.", "Basic and block styles are basically the same, but the stroke order is different. Basic is what is often taught when Japanese students first learn the alphabet. Block is the version I think most people would actually use in real life."],
                    
                    workswith : {
                        explorer : "Partially supported in Internet Explorer version 9, but animations do not work.",
                        firefox : "Fully supported since Firefox 4",
                        opera : "Fully supported since Opera 11",
                        chrome : "Fully supported since Chrome 10"
                    },
                    
                    pageTags : ["abc", "alphabet", "penmanship", "handwriting", "letter", "lab", "_"]
                    
                }/*,
                
                page_daimyo : {
                    pageName : "",
                    url : "",
                    shortDescription : "",
                    longDescription : [""],
                    
                    ff : 4,
                    opera : 11,
                    chrome : 11,
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_prefectures : {
                    pageName : "",
                    url : "",
                    shortDescription : "",
                    longDescription : [""],
                    
                    ff : 4,
                    opera : 11,
                    chrome : 11,
                    
                    pageTags : ["", "_"]
                    
                },
                
                page_flashcardinator : {
                    pageName : "",
                    url : "",
                    shortDescription : "",
                    longDescription : [""],
                    
                    ff : 4,
                    opera : 11,
                    chrome : 11,
                    
                    pageTags : ["", "_"]
                    
                }
                */
                
            }
            
            
        },
        
        group_misc : {
            groupName : "Miscellaneous stuff",
            groupDescription : "",
            
            section_home : {
                sectionName : "Home",
                sectionDescription : "",
                
                announcements : {
                    
                    _13 : {
                        anntype : "update",
                        anndate : "2012.01.27",
                        anntitle : "Added comments section to <em>Vocablinator</em> update page",
                        anncontent : {
                            _p01 : "<a href='/vocablinator'>Vocablinator</a>",
                            _p02 : "You can now leave comments, queries or suggestions in the comments section."
                        }
                    },
                    _12 : {
                        anntype : "new",
                        anndate : "2012.01.21",
                        anntitle : "Created <em>Shade</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/shade'>Shade</a>",
                            _p02 : "You can choose from various flashcards and display them on the interactive whiteboard. You can also choose to hide them with several different kinds of shades, for 'What's this?'-style activities."
                        }
                    },
                    _11 : {
                        anntype : "new",
                        anndate : "2012.01.12",
                        anntitle : "Created update page for <em>Vocablinator</em>",
                        anncontent : {
                            _p01 : "<a href='/vocablinator'>Vocablinator update</a>",
                            _p02 : "The Vocablinator is in the works, and I need your help! If you have free time, you can submit words from the textbook indexes for the new word database, and be forever immortalized as a contributor."
                        }
                    },
                    _10 : {
                        anntype : "new",
                        anndate : "2011.11.05",
                        anntitle : "Created <em>Wackie Races</em> scorer page",
                        anncontent : {
                            _p01 : "<a href='/wackieraces'>Wackie Races</a>",
                            _p02 : "A super-jazzed-up version of Not Particularly Wacky Races, with several animated visual styles to choose from."
                        }
                    },
                    _09 : {
                        anntype : "update",
                        anndate : "2011.11.05",
                        anntitle : "Updated <em>ABC Colo(u)r</em> page",
                        anncontent : {
                            _p01 : "<a href='/abccolor'>ABC Colo(u)r</a>",
                            _p02 : "Now when you bookmark the page, your settings will be saved, so you can come back to the page exactly as you left it. It has also been optimized a little for slightly faster loading."
                        }
                    },
                    _08 : {
                        anntype : "new",
                        anndate : "2011.07.16",
                        anntitle : "Created an interactive set of virtual dice - the <em>Dice</em> page",
                        anncontent : {
                            _p01 : "<a href='/dice'>Dice</a>",
                            _p02 : "Click on any die to roll it, or roll all the dice at once. Choose from one to six dice, in a rainbow of beautiful colours."
                        }
                    },
                    _07 : {
                        anntype : "update",
                        anndate : "2011.07.10",
                        anntitle : "Updated altastic.com",
                        anncontent : {
                            _p01 : "The new version of altastic is up and (as far as I can tell) working fine. Do let me know if you notice anything amiss. Unless, of course, it's the <a href='#contact' alt='Contact page'>contact</a> page that's not working; in that case I guess we are just screwed.",
                            _p02 : "Questions ('<em>Why did you change everything?</em>'), comments ('<em>The old one was way better!</em>'), suggestions ('<em>Change it back, right now!</em>') are all most welcome."
                        }
                    },
                    _06 : {
                        anntype : "new",
                        anndate : "2011.07.04",
                        anntitle : "Created a <em>Numbers</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/numbers'>Numbers</a>",
                            _p02 : "A flashcard page for displaying numbers, which I have (in a stroke of originality rarely seen since the Renaissance) 'Numbers'. You can easily select a range (or several) of numbers from zero to 99,999. Both simple digits and words are displayed, though both can be toggled on or off."
                        }
                    },
                    _05 : {
                        anntype : "new",
                        anndate : "2011.07.04",
                        anntitle : "Created a flashcard page for irregular verbs - <em>the Verbinator</em>",
                        anncontent : {
                            _p01 : "<a href='/verbinator'>The Verbinator</a>",
                            _p02 : "Display some of the most common English irregular verbs in both List and Flashcard modes. Includes the verbs' principle parts (present, past, and past participle), along with their meaning in Japanese."
                        }
                    },
                    _04 : {
                        anntype : "update",
                        anndate : "2011.07.03",
                        anntitle : "Updated the <em>Flags of the World</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/flags'>Flags of the World</a>",
                            _p02 : "Now featuring a search tool to make flag selection easier. It's also been optimized to load a little faster than before."
                        }
                    },
                    _03 : {
                        anntype : "update",
                        anndate : "2011.07.02",
                        anntitle : "Updated the <em>What's This</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/whatsthis'>What's This</a>",
                            _p02 : "Pretty much the same, functionalitywise, but hopefully a bit easier to use."
                        }
                    },
                    _02 : {
                        anntype : "update",
                        anndate : "2011.06.24",
                        anntitle : "Updated the <em>ABC</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/abc'>ABC</a>",
                            _p02 : "It's now faster-loading, more aesthetically pleasing, and features reworked letters in both block and cursive styles."
                        }
                    },
                    _01 : {
                        anntype : "update",
                        anndate : "2011.06.24",
                        anntitle : "Updated the <em>ABC Colo(u)r</em> flashcard page",
                        anncontent : {
                            _p01 : "<a href='/abccolor'>ABC Colo(u)r</a>",
                            _p02 : "You are no longer required to select a single picture to display alongside each letter; each letter's images can be cycled through freely. It should also load a little faster, and (I think) looks a lot nicer than the old version."
                        }
                    }
                    
                    /*,
                    _00 : {
                        anntype : "",
                        anndate : "",
                        anntitle : "",
                        anncontent : {
                            _p01 : "",
                            _p02 : ""
                        }
                    }*/
                    
                },
                
                drawContent : function () {
                    
                    //make the lower part of the content - sectionContent
                    var sectionContent = $.makeDiv("section_content");
                        
                        sectionContent.appendChild($.makeAnchor("/vocablinator", null, "a_n_y", [$.makeImg("vocablinator/altasticwantsyou.png", "Help create the Vocablinator database", null, "a_n_y")]));
                        
                        var ANY = sectionContent.appendChild($.makeDiv(null, "a_n_y"));
                            ANY.appendChild($.makeP("The new textbooks are coming out soon, so it's finally time for the New Horizon vocabulary pages to be updated. This time we're going to make a database for all six sets of textbooks - New Horizon, New Crown, Total English, Sunshine, One World, and Columbus 21. It's a daunting task, so I want your help! It's really easy. Each textbook has a word list at the back - enter the information for just one of the words and you'll bring us a step closer to our goal. You'll also be immortalized in a list of contributors once the whole thing's completed. Exciting, no?!"));
                        
/*                        var oNNexpl = sectionContent.appendChild($.makeDiv("niigatanoise_expl"));
                            oNNexpl.appendChild($.makeP("Check out the new Niigata AJET newsletter! It's new! And shiny!"));
                        
                        var oNNembed = sectionContent.appendChild($.makeDiv("niigatanoise_embed"));
                            oNNembed.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" style="width:600px;height:400px" id="955638e0-c476-986e-f2e6-c43a5f658217" ><param name="movie" value="http://static.issuu.com/webembed/viewers/style1/v2/IssuuReader.swf?mode=mini&amp;autoFlip=true&amp;shareMenuEnabled=false&amp;backgroundColor=%23222222&amp;documentId=111220020103-dbf0c2a5a7d141748c775524c8cb0b93" /><param name="allowfullscreen" value="true"/><param name="menu" value="false"/><param name="wmode" value="transparent"/><embed src="http://static.issuu.com/webembed/viewers/style1/v2/IssuuReader.swf" type="application/x-shockwave-flash" allowfullscreen="true" menu="false" wmode="transparent" style="width:600px;height:400px" flashvars="mode=mini&amp;autoFlip=true&amp;shareMenuEnabled=false&amp;backgroundColor=%23222222&amp;documentId=111220020103-dbf0c2a5a7d141748c775524c8cb0b93" /><noembed><a href="http://issuu.com/niigatanoise/docs/niigatanoise1?mode=window&amp;backgroundColor=%23222222"><img src="images/previews/nn_1.png" alt="Niigata Noise"></a></noembed></object><div style="width:600px;text-align:left;"><a href="http://issuu.com/niigatanoise/docs/niigatanoise1?mode=window&amp;backgroundColor=%23222222" target="_blank">Open publication</a> - Free <a href="http://issuu.com" target="_blank">publishing</a></div>';
*/                        
                            
                        
                        //sectionContent.appendChild($.makeSpan("<em><strong>NOTE:</strong> Some pages may not function correctly when used in Internet Explorer 9 with the DivX plugin installed. This error is acknowledged by DivX, who say that it will be fixed in a future release of the plugin. I apologise to anyone affected by this, but due to the nature of the bug, I am not in a position to be able to fix it. A temporary workaround is to disable the DivX plugin and restart the browser.</em>"));
                        
                        //get announcements
                        sectionContent.appendChild($.makeHdr(2, "Announcements"));
                            
                            var eAnnTable = document.createElement("table");
                                var eAnnTbody = document.createElement("tbody");
                                
                                //only show at most 10 announcements
                                var k = 0;
                                
                                var announcements = oAltastic.bank.group_misc.section_home.announcements;
                                for (var m in announcements) {
                                    if (k > 9) break;
                                    k++;
                                    
                                    var newtr = document.createElement("tr");
                                        
                                        var iconTD = document.createElement("td");
                                            iconTD.className = "announcement";
                                            iconTD.appendChild($.makeImg("images/icons/" + announcements[m].anntype + ".png", "", null, "announcement_icon"));
                                        
                                        var dateTD = document.createElement("td");
                                            dateTD.className = "announcement";
                                            var annDate = dateTD.appendChild($.makeDiv(null, "announcement_date"));
                                                annDate.appendChild($.makeSpan(announcements[m].anndate));
                                        
                                        var textTD = document.createElement("td");
                                            textTD.className = "announcement";
                                            
                                            var annToggler = $.makeAnchor("#", null, "announcement_title");
                                                annToggler.appendChild($.makeHdr(4, announcements[m].anntitle, null, "announcement_title"));
                                                annToggler.onclick = function () {
                                                    var detail = this.parentNode.getElementsByTagName("div")[0];
                                                        detail.className = (detail.className == "announcement_detail appear") ? "announcement_detail vanish" : "announcement_detail appear";
                                                        
                                                    return false;
                                               };
                                            
                                            var annDetail = $.makeDiv(null, "announcement_detail vanish");
                                                for (var k in announcements[m].anncontent) {
                                                    annDetail.appendChild($.makeP(announcements[m].anncontent[k]));
                                                }
                                                
                                            textTD.appendChild(annToggler);
                                            textTD.appendChild(annDetail);
                                            
                                        newtr.appendChild(iconTD);
                                        newtr.appendChild(dateTD);
                                        newtr.appendChild(textTD);
                                        
                                    eAnnTbody.appendChild(newtr);
                                }
                                
                            eAnnTable.appendChild(eAnnTbody);
                            
                            
                        sectionContent.appendChild(eAnnTable);
                        
                        
                    oAltastic.content.appendChild(sectionContent);
                    
                    return;
                }
                
            },
            
            section_contact : {
                sectionName : "Contact",
                sectionDescription : "If you have any questions, comments or suggestions, don't hesitate to drop me a line.",
                
                subjects : {
                    _01 : "General comment",
                    _02 : "Idea for a new page",
                    _03 : "A way to improve an existing page",
                    _04 : "Report an error",
                    _05 : "Report images"
                },
                
                drawContent : function () {
                    
                    var sectionContent = $.makeDiv("section_content");
                        
                        //the explanatory paragraph
                        var eExplP = $.makeP("Send me your comments below. You don't have to supply a name or email address unless you want me to get back to you. I promise not to divulge any personal information; details can be found on the <a href='#about'>about page</a>.", null, "smallp");
                        
                        sectionContent.appendChild(eExplP);
                        
                        var eAjaxForm = document.createElement("form");
                            eAjaxForm.setAttribute("id", "contact");
                            eAjaxForm.setAttribute("name", "contact");
                            eAjaxForm.setAttribute("method", "post");
                            
                            //the name box and label
                            var fnamediv = $.makeDiv(null, "contact");
                                var fnamelbl = document.createElement("label");
                                    fnamelbl.innerHTML = "Name: ";
                                fnamediv.appendChild(fnamelbl);
                                
                                var fnametext = document.createElement("input");
                                    fnametext.setAttribute("type", "text");
                                    fnametext.setAttribute("id", "fname");
                                    fnametext.className = "contact_textbox";
                                fnamediv.appendChild(fnametext);
                            eAjaxForm.appendChild(fnamediv);
                            
                            //the email box, label and alert span
                            var emaildiv = $.makeDiv(null, "contact");
                                var emaillbl = document.createElement("label");
                                    emaillbl.innerHTML = "Email: ";
                                emaildiv.appendChild(emaillbl);
                                
                                var emailtext = document.createElement("input");
                                    emailtext.setAttribute("type", "text");
                                    emailtext.setAttribute("id", "email");
                                    emailtext.className = "contact_textbox";
                                emaildiv.appendChild(emailtext);
                                
                                emaildiv.appendChild(document.createElement("br"));
                                
                                var emailspan = document.createElement("span");
                                    emailspan.setAttribute("id", "email_alert");
                                    emailspan.className = "input_alert";
                                    emailspan.innerHTML = "";
                                emaildiv.appendChild(emailspan);
                            eAjaxForm.appendChild(emaildiv);
                            
                                
                            //the select
                            var subjectdiv = $.makeDiv(null, "contact");
                                var subjectlbl = document.createElement("label");
                                    subjectlbl.innerHTML = "Subject: ";
                                subjectdiv.appendChild(subjectlbl);
                                
                                var selector = document.createElement("select");
                                    selector.setAttribute("id", "subject");
                                    selector.className = "contact_select";
                                    
                                    var subjects = oAltastic.bank.group_misc.section_contact.subjects;
                                    var s = 0;
                                    for (var k in subjects) {
                                        selector.options[s] = new Option(subjects[k], s);
                                        s++;
                                    }
                                    
                                subjectdiv.appendChild(selector);
                            eAjaxForm.appendChild(subjectdiv);
                            
                            //the comment textarea and alert span
                            var commentdiv = $.makeDiv(null, "contact");
                                var commenttext = document.createElement("textarea");
                                    commenttext.setAttribute("id", "comment");
                                    commenttext.className = "contact_textarea";
                                commentdiv.appendChild(commenttext);
                                
                                commentdiv.appendChild(document.createElement("br"));
                                
                                var commentspan = document.createElement("span");
                                    commentspan.setAttribute("id", "comment_alert");
                                    commentspan.className = "input_alert";
                                    commentspan.innerHTML = "";
                                commentdiv.appendChild(commentspan);
                            eAjaxForm.appendChild(commentdiv);
                            
                            
                            //the submit button
                            var submitdiv = $.makeDiv(null, "contact submit");
                                var submitbtn = document.createElement("input");
                                    submitbtn.setAttribute("type", "submit");
                                    submitbtn.setAttribute("id", "submit");
                                    submitbtn.className = "submit";
                                    submitbtn.value = "Send";
                                    submitbtn.onclick = function () {
                                        var inputchecked = oAltastic.submitContactForm(this);
                                        //if the user input was okay, we can disable the form till we get an ajax confirmation
                                        if (inputchecked) {
                                            this.disabled = true;
                                            this.value = "Sending...";
                                            document.getElementById("fname").disabled = true;
                                            document.getElementById("email").disabled = true;
                                            document.getElementById("subject").disabled = true;
                                            document.getElementById("comment").disabled = true;
                                        }
                                        return false;
                                    }
                                submitdiv.appendChild(submitbtn);
                            eAjaxForm.appendChild(submitdiv);
                            
                        sectionContent.appendChild(eAjaxForm);
                        
                    oAltastic.content.appendChild(sectionContent);
                    
                    return;
                    
                }
                
            },
            
            section_faq : {
                sectionName : "FAQ",
                sectionDescription : "",
                
                faqbank : {
                    _01 : {
                        faqsectname : "About the webmaster",
                        faqs : {
                            _01 : {
                                q : "Who are you? Why did you make this site?",
                                a : ["My name is Vid. I'm a teacher of English. I made this site because nobody else did. And I'm a geek."]
                            },
                            _02 : {
                                q : "You're awesome. Can I give you money?",
                                a : ["No. I appreciate the thought, and much as I love money, I'd rather educational things be free of charge. I have a job at the moment, and I enjoy programming and web design immensely, so I don't mind paying the web hosting fees myself. If I'm ever in a situation where I really cannot afford it, I might set up some way for you to donate, but not for the moment."]
                            }
                        }
                        
                    },
                    
                    _02 : {
                        faqsectname : "Troubleshooting",
                        faqs : {
                            _01 : {
                                q : "Why do some pages not work on my computer?",
                                a : ["Nearly all the pages require you to have Javascript and stylesheets (CSS) enabled in your browser. Make sure they are both enabled. A couple of pages require Java to be installed, so make sure you have the latest version. If all else fails, let me know via the contact page, and I'll resolve the issue. I try to test all the pages in all the web browsers I can, but I've doubtless missed a few things.", "A note on Internet Explorer 6: I assidiously test all pages in all the browsers available to me. Until the last revision of the site, this included IE6. However, due to circumstances beyond my control, I now have literally no way to test in IE6, so I've (not entirely reluctantly) had to drop support for it. I have never seen the new site in IE6, but given my past experience with it, I would almost guarantee that the page layouts look odd and half the functionality is missing. There is nothing I can do about this for the moment, and frankly I don't foresee a situation in which I will ever have the means to.", "I do test the site in Internet Explorer 7+, Firefox, Opera, Chrome and Safari on Vista and Windows 7. I also test in Ubuntu. If you are using any of those browsers, and the page looks odd or doesn't work as expected, then it is a bug. Please tell me about it via the contact page, and I will endeavour to fix the problem as soon as I can.", "Some pages have bugs that are known to me, but for which a workaround has not yet been devised. I hate releasing things half-finished, but if the bug is minor enough, I think the potential benefits from having something outweigh the drawbacks from having nothing. Where this is the case, I have noted it in the page's explanation."]
                            },
                            _02 : {
                                q : "Why doesn't the page fit in the window?",
                                a : ["I designed most of the pages to be about 980 pixels wide and 720 pixels high. On some computers this may look too small or too large. All modern browsers have a zoom function, which you can use to solve this problem. The zoom function can be accessed from the various browsers' menus, but the quickest way to do it is via the keyboard shortcuts - <span class='key'>&nbsp;CTRL&nbsp;</span> &amp; <span class='key'>&nbsp;+&nbsp;</span> to zoom in, <span class='key'>&nbsp;CTRL&nbsp;</span> &amp; <span class='key'>&nbsp;-&nbsp;</span> to zoom out, and <span class='key'>&nbsp;CTRL&nbsp;</span> &amp; <span class='key'>&nbsp;0&nbsp;</span> to reset the zoom. On some pages using the browser zoom will cause the page to stop working properly; where this is the case I have noted it on the page description."]
                            },
                            _03 : {
                                q : "Why doesn't zoom work?",
                                a : ["I made a lot of these pages before I knew about how browser zooming worked. The way I programmed things, the calculations that are made to determine where the mouse is on the page are thrown off when the page size is not 100%. I am working on a way around this problem.", "This is also a problem, but for different reasons, on the Clock and Nations Quiz pages. Those pages use Java, and the Java applet is embedded in the browser in such a way that zooming won't make the actual applet any bigger. This is also a problem I am aware of, and will fix as soon as I figure out how.", "I apologise for the inconvenience."]
                            },
                            _04 : {
                                q : "How do I enable Javascript?",
                                a : "<ul><li><strong>Firefox:</strong> Click on Edit -> Preferences, and select the Content tab. Check the Enable Javascript box.</li><li><strong>Internet Explorer:</strong> Click on Tools -> Internet Options, and select the Security tab. Click on the Custom level button. Scroll down to the Script section and check Active Scripting -> Enable.</li><li><strong>Google Chrome:</strong> Javascript is enabled by default in Chrome. There is no simple, user-friendly method to disable it. For those who want to, there are tutorials out there, such as <a href='http://mistered.us/tips/javascript/chrome.shtml' alt='How to enable Javascript in Google Chrome'>this one</a>.</li><li><strong>Opera:</strong> Click on Tools -> Preferences, and select the Advanced tab. Click on Content and check the Enable Javascript box.</li><li><strong>Konqueror:</strong> Click on Settings -> Configure Konqueror -> Java &amp; Javascript, and select the Javascript tab. Check the Enable Javascript globally box.</li><li><strong>Safari:</strong> Click on Edit -> Settings and select the Security tab. Check the Enable Javascript box.</li></ul>"
                            },
                            _05 : {
                                q : "Where can I get Java?",
                                a : ["The latest version of Java, required for a couple of pages on this site, can be <a href='http://www.java.com/en/download/index.jsp' alt='Java download page'>downloaded here</a>."]
                            }
                        }
                        
                    },
                    
                    _03 : {
                        faqsectname : "(Re)Sources",
                        faqs : {
                            _01 : {
                                q : "Can I submit an idea for a page?",
                                a : ["Sure, on the <a href='#contact' alt='Contact page'>contact page</a>. If I think your idea is workable, I'll give it a shot, and you'll get full credit when/if it works out."]
                            },
                            _02 : {
                                q : "Where do you get the images you use on the site?",
                                a : ["Apart from the ABC Flashcards and the What's This images, which were both my own creations, I get almost all the images from <a href='http://www.openclipart.org/' alt='OpenClipArt.org'>OpenClipArt.org</a>, a site dedicated to sharing public domain clipart. Something in the public domain is totally free to download and modify, and since I have no money to buy decent artwork, and no artistic skill with which to produce it myself, the public domain is my heaven. Some of the background images come from <a href='http://www.publicdomainpictures.net/' alt='PublicDomainPictures.net'>PublicDomainPictures.net</a>, and some from <a href='http://www.texturise.com/' alt='texturise.com'>texturise.com</a>, both excellent sites, and both also offering beautiful artwork for free. The flag images are modified versions of those downloaded from <a href='http://www.flagpedia.net/' alt='Flagpedia.net'>Flagpedia.net</a>, which also has a wealth of other information about each and every country in this little world of ours. I highly recommend it."]
                            },
                            _03 : {
                                q : "Can I distribute the things I download on the Resources page?",
                                a : ["All of the downloads should contain a README text file, which explains among other things what the usage rights are. Generally speaking, the offline versions of pages are free to redistribute as long as you don't change them. The images are free to redistribute if they are ones that I created, which is most of them. Not all of them are, however, so check the readme file carefully before you make any assumptions.", "I think that it is probably a bad idea (and utterly futile) to attempt to stop people sharing these things. In general, however, I would prefer that people download everything from the site itself."]
                            }
                        }
                        
                    },
                    
                    _04 : {
                        faqsectname : "Miscellaneous",
                        faqs : {
                            _01 : {
                                q : "Can you make a vocabulary page for a textbook besides New Horizon?",
                                a : ["I'm currently waiting for the new textbooks to be released, which should happen in the next year or so. Once they are available, and depending on my schedule, I will try to add as many textbooks as I can. It will take a fair amount of time, though; creating the vocabulary database for each book is an insanely time-consuming (not to mention spirit-crushingly dull) process."]
                            },
                            _02 : {
                                q : "What's the best way to cook a chicken?",
                                a : ["Roasting is the simplest way to cook a whole chicken. First remove the giblets (they're usually wrapped in paper inside the cavity) and rinse the chicken well, inside and out, with cold water. Pat it dry an pull off any globs of fat around the cavity. Next, squeeze half an orange or lemon over the skin and rub it inside the cavity. Sprinkle the bird with salt, pepper, and a dash of paprika. Lay a few dots of butter on the back and legs d place the chicken in a roasting pan just large enough to hold it (use a ck if you've got one). Roast the chicken on the center rack of a preheated 350'F oven. Cook for 20 minutes per pound (about I hour 10 minutes for an average-size broiler/fryer), or until the juices run clear when a thigh joint is pricked with a knife."]
                            }
                        }
                        
                    }
                    
                    
                },
                
                drawContent : function () {
                    
                    var sectionContent = $.makeDiv("section_content");
                        
                        var faqsections = oAltastic.bank.group_misc.section_faq.faqbank;
                        for (var k in faqsections) {
                            
                            sectionContent.appendChild($.makeHdr(3, faqsections[k].faqsectname, null, "faqhead"));
                            
                            for (var m in faqsections[k].faqs) {
                                
                                //make a div to contain the question
                                var eFaqDiv = $.makeDiv("faq" + m, "faqdiv");
                                
                                //print the question
                                var q = $.makeAnchor("#", null, "faq_q");
                                    q.appendChild($.makeHdr(4, faqsections[k].faqs[m].q, null, "faq_q"));
                                    q.onclick = function () {
                                        var ps = this.parentNode.getElementsByTagName("div");
                                        for (var n = 0; n < ps.length; n++) {
                                            if (ps[n].className == "vanish") {
                                                ps[n].className = "faq_ans";
                                            }
                                            else {
                                                ps[n].className = "vanish";
                                            }
                                        }
                                        return false;
                                    };
                                eFaqDiv.appendChild(q);
                                
                                //and print all the answers as paragraphs. faqs can have one Q and multiple As.
                                
                                var faqans = $.makeDiv(null, "vanish");
                                
                                var answers = faqsections[k].faqs[m].a;
                                
                                if (typeof answers  == 'string') {
                                    
                                    faqans.innerHTML = answers;
                                    
                                }
                                else {
                                    for (var r = 0; r < answers.length; r++) {
                                        faqans.appendChild($.makeP(answers[r]));
                                    }
                                }
                                eFaqDiv.appendChild(faqans);
                                
                                sectionContent.appendChild(eFaqDiv);
                                
                            }
                            
                        }
                        
                    oAltastic.content.appendChild(sectionContent);
                    
                    return;
                    
                }
                
            },
            
            section_about : {
                sectionName : "About",
                sectionDescription : "",
                
                aboutbank : {
                    _01 : {
                        aboutname : "Site History",
                        txt_00 : "This is the fourth incarnation of a site I originally set up to host a few personal pages. The first educational (and I use the term in its loosest possible sense) page was what eventually became the Scramblinator. I then spent many arduous weeks developing the New Horizon vocabulary pages, because I'm evidently both too lazy to use a book index, and too foolish to realize that developing said pages would require way more work. Anyway, in the hopes that someone else might find these things useful, I made the site public.",
                        txt_01 : "For a while that's all there was. Then, the school at which I worked installed interactive whiteboards in every classroom. It occurred to me that I could save a lot of time and resources on things like flashcard-making (up until that point, a major part of my job), and so I started making more pages. There are now quite a few, and I'll keep adding to them as ideas occur to me."
                    },
                    _02 : {
                        aboutname : "Compatibility",
                        txt_00 : "Ever since I read about the concept on <a href='http://www.quirksmode.org' alt='Peter-Paul Koch's Quirksmode'>PPK's wonderful site</a>, I have strived for cross-browser compatibility in everything I develop. This, despite the fact that I'd wager almost anything that the vast majority of educational institutions are running Microsoft Internet Explorer. I could have just designed the pages entirely around <abbr title='Microsoft Internet Explorer'>MSIE</abbr>, but my sense of responsibility to potential users of other browsers (or my chronic OCD, one of the two) forces me to make everything compatible. I therefore test everything in all the browsers I have access to. However, I am not perfect, so I am sure some errors will have slipped through. If you notice anything peculiar, any bizarre quirks in display or functionality, do please <a href='#contact' alt='Contact page'>let me know about it</a>, and I'll fix the issue as soon as I can.",
                        txt_01 : "All the HTML, PHP, CSS and SVG files passed W3C Validation.",
                        txt_02 : "<img src='images/icons/valid-html401.gif' alt='Valid HTML 4.01' ><img src='images/icons/valid-css2.gif' alt='Valid CSS Level 2' ><img src='images/icons/valid-svg11.gif' alt='Valid SVG 1.1' >"
                    },
                    _03 : {
                        aboutname : "Accessibility",
                        txt_00 : "Something I've started trying to do recently, and have attempted in this redesign of altastic, is to make the site more accessible. By this I mean accessible to users whose browsing experience differs from the mainstream, be it because of physical disabilities or lack of access to modern browsers.",
                        txt_01 : "However, the fact of the matter is that a majority of the pages I've made rely heavily on visual elements. Flashcards, scorers, and other stuff designed for the interactive whiteboard are inherently visual. To be frank, I'm not really certain in what way these things could be made to be more accessible. I have endeavored to add keyboard shortcuts for as many pages as possible, and am working on a number of versions that do not rely on Cascading Style Sheets. However, it's a lot of work, especially as I'm not entirely sure what kind of user I'm aiming at while I design them (or even if there are such users).",
                        txt_02 : "Bearing this in mind, I hope you will understand that to make non-Javascript versions of the interactive pages would be an even more monumental task, and so I am not even attempting to do that at the moment. I'm not deaf to ideas, however, and if you have a specific suggestion about accessibility, I'd love to hear from you.",
                        txt_03 : "At any rate, I have also written some very basic versions of the main pages for those who do not have Javascript enabled. These will enable such users to at least download some of the resources, and hopefully make up for the site's accessibility shortcomings."
                    },
                    _04 : {
                        aboutname : "Images",
                        txt_00 : "Information about the images used on this website and available for download from the <a href='#resources'>resources</a> page.",
                        h_01 : "Copyrighted logos",
                        txt_01 : "The web browser and Java logos used on the pages in the Lab section were obtained from <a href='http://commons.wikimedia.org/'>Wikimedia Commons</a>. Although (with the exception of the Opera logo) they are all copyrighted, I believe their usage on this site can be judged as fair use. They are only present to inform a user of whether a page will function correctly in a given browser, or whether the page requires Java or not. I'm not presenting any information that isn't true. If I'm wrong, and it is not fair use, <a href='#contact' alt='Contact page'>let me know</a> and I will take them down immediately.",
                        h_02 : "Main page header and footer",
                        txt_02 : "The background header and footer images were originally downloaded for the most part from <a href='http://www.publicdomainpictures.net/'>PublicDomainPictures.net</a>, apart from some which were taken by myself. They have been altered for size and shape. I believe the images are all in the public domain.",
                        h_03 : "<em>ABC</em> Flashcards",
                        txt_03 : "The images used on the ABC Flashcards page were created by me using <a href='http://inkscape.org/'>Inkscape</a>. The letters are based on the alphabet as taught in Japanese junior high school textbooks. Occasionally I referenced the Zaner-Bloser family of fonts for clarification, but the paths were all painstakingly traced by my own fair hand. This means that they are probably not perfect, but I did the best I could with my limited artistic skills. The images are free to download and use for non-commercial purposes. I don't require that you credit me, but I would appreciate being informed if you do use the images for something public.",
                        h_04 : "<em>ABC Colo(u)r</em> Flashcards",
                        txt_04 : "The images used on the ABC Color Flashcards pages were composited by me using <a href='http://inkscape.org/'>Inkscape</a>. The pictures contained within the images (ant, bag, cap, etc) are all either from <a href='http://www.clker.com/'>Clker.com</a> or the <a href='http://www.openclipart.org/'>Open Clip Art Library</a>, and I believe they are all in the public domain. Since the original images were in the public domain, you are free to download and use my modified images for any purpose.",
                        h_05 : "<em>What's this?</em> Flashcards",
                        txt_05 : "The images used on the What's this? page were all taken by me at a school at which I worked. Some of them contain copyrighted items, such as the POSCA pen. Since I am using them for educational purposes, and the reputation of the companies involved is not being tarnished in any way, I believe they fall under fair use terms. You are free to download them for personal use, but I advise you not use them for public consumption unless you are certain you are allowed to.",
                        h_06 : "<em>Flags of the World</em> Flashcards",
                        txt_06 : "The flag images were all generated from PNGs downloaded from the excellent <a href='http://flagpedia.net/'>Flagpedia.net</a>. I highly recommend a visit to Flagpedia; aside from the fantastic flags, there is a wealth of other information about all the countries of this fair little planet. As far as I know, all flags are ineligible for copyright, so I believe they are all in the public domain.",
                        txt_07 : "Notwithstanding the above explanations, if informed that the use of any image is not permitted for whatever reason, I will take it down immediately upon request."
                    },
                    _05 : {
                        aboutname : "Documents",
                        txt_00 : "The documents on the <a href='#resources'>resources</a> page were all written either by me or by mypredecessors and colleagues. They are intended to make life a little easier for foreigners living in Japan.",
                        txt_01 : "Because they are all written from experience, and none of the writers were affiliated in any way with what they were writing about, it is possible that some of them contain factual errors. If this is the case, please <a href='#contact' alt='contact page'>let me know</a> and I will alter them.",
                        txt_02 : "The documents are, however, provided on an as-is basis, guaranteeing nothing at all, so I cannot be held responsible for any problems that arise from their use."
                    },
                    _06 : {
                        aboutname : "Privacy",
                        txt_00 : "I collate no personal information about any user. If you contact me using either the <a href='#contact' alt='Contact page'>contact page</a> or via email, and you choose to include a return address, know that I will never share it with anyone. The same goes for your name and the contents of the correspondence. The only exceptions are if you give me express permission to do so (for example, to give you credit for a new page idea) or if I am legally forced to do so for some reason."
                    },
                    _07 : {
                        aboutname : "General Disclaimer",
                        txt_00 : "I offer everything on this site free of charge, for use by anyone. While I had nothing but positive intentions in making it all, I can make absolutely no guarantees about the quality, correctness or usability of anything on altastic."
                    }
                },
                    
                drawContent : function () {
                    
                    var sectionContent = $.makeDiv("section_content");
                        
                        var abouts = oAltastic.bank.group_misc.section_about.aboutbank;
                        for (var k in abouts) {
                            
                            for (var m in abouts[k]) {
                                
                                if (m == "aboutname") {
                                    sectionContent.appendChild($.makeHdr(3, abouts[k][m], null, "about"));
                                }
                                else if (/^txt_\d+/.test(m)) {
                                    sectionContent.appendChild($.makeP(abouts[k][m], null, "about"));
                                }
                                else if (/^h_\d+/.test(m)) {
                                    sectionContent.appendChild($.makeHdr(4, abouts[k][m], null, "about"));
                                }
                                
                            }
                            
                        }
                        
                    oAltastic.content.appendChild(sectionContent);
                    
                    return;
                    
                }
                
            }
            
            
        }
    }
    
}
window.onload = oAltastic.resources.loadResources;
