// Invasion of the Body Switchers
// This copyright statement must remain in place for both personal and commercial use
// ***********************************************************************************
// Creative Commons License -- http://creativecommons.org/licenses/by-nc-nd/2.0/
// Original concept and article by Malarkey (Andy Clarke) -- http://www.stuffandnonsense.co.uk/
// DOM scripting by Brothercake (James Edwards) -- http://www.brothercake.com/
// Create element and attributes based on a method by beetle -- http://www.peterbailey.net/
//************************************************
//open initialisation function
function iotbs() {
    switcher = new switchManager();
    //************************************************



    /*****************************************************************************
    Define switching controls
    *****************************************************************************/


    //create a switcher form ('container-id', 'label')
    var screenSwitcher = new bodySwitcher('screen-switcher', 'Modalita\' pagina');

    //add a new class option ('classname', 'label')
    screenSwitcher.defineClass('default', 'Normale');
    screenSwitcher.defineClass('high', 'Caratteri grandi');
    screenSwitcher.defineClass('highvisibility', 'Alta visibilita\'');



    /*****************************************************************************
    *****************************************************************************/



    //close initialisation function
};


//global preferences manager reference
var switcher;


//setup initialisation function
//.. gecko, safari, konqueror and generic
if (typeof window.addEventListener != 'undefined') {
    window.addEventListener('load', iotbs, false);
}
//.. opera 7
else if (typeof document.addEventListener != 'undefined') {
    document.addEventListener('load', iotbs, false);
}
//.. win/ie
else if (typeof window.attachEvent != 'undefined') {
    window.attachEvent('onload', iotbs);
}


//preferences manager 
function switchManager() {
    //string for storing the overall custom classname
    //I was originally storing it in the body class name directly
    //but 1.7+ mozilla builds were not honouring the trailing whitespace we need
    this.string = '';

    //store reference to body element
    this.body = document.getElementsByTagName('body')[0];

    //store the initial classname
    this.initial = this.body.className;

    //if the default classname is empty, add "iotbs"
    //because we need there to be at least one classname already - 
    //the leading and trailing space in each custom classname is required, 
    //but you can't set the body classname as " something" (beginning with a leading space)
    //because that may not work in Opera 7
    if (this.initial == '') {
        this.initial = 'itobs';
    }

    //look for a stored cookie
    this.cookie = this.read();

    //if it exists
    if (this.cookie != null) {
        //store cookie value to string
        this.string = this.cookie;

        //set new body class name
        this.body.className = this.initial + this.string;
    }

    //*** dev
    //document.title = '<' + this.body.className.replace(/ /g,'+') + '>   [' + this.string.replace(/ /g,'+') + ']';

};

//set a cookie method
switchManager.prototype.set = function (days) {
    //format expiry date
    this.date = new Date();
    this.date.setTime(this.date.getTime() + (days * 24 * 60 * 60 * 1000));

    //store the string, replacing spaces with '#' so that leading spaces are preserved
    this.info = this.string.replace(/ /g, '#');

    //if the value is empty, set its expiry in the past to delete the cookie
    if (this.info == '') { this.date.setTime(0); }

    //create the cookie
    document.cookie = 'bodySwitcher=' + this.info
		+ '; expires=' + this.date.toGMTString()
		+ '; path=/';

};


//read a cookie method
switchManager.prototype.read = function () {
    //set null reference so we always have something to return
    this.cookie = null;

    //if a cookie exists
    if (document.cookie) {
        //if it's our cookie
        if (document.cookie.indexOf('bodySwitcher') != -1) {
            //extract and store relevant information (turning '#' back into spaces)
            this.cookie = document.cookie.split('bodySwitcher=');
            this.cookie = this.cookie[1].split(';');
            this.cookie = this.cookie[0].replace(/#/g, ' ');
        }
    }

    return this.cookie;
};


//switcher form constructor
function bodySwitcher(divid, label) {

    //create an associate array of classnames for this option
    //so we can later iterate through and remove them from the custom classname string
    this.classes = [];

    //start counting options, because we'll need the index of each option as it's created
    //so that an option can be selected by default if necessary
    this.options = 0;

    //outer form
    this.attrs = { 'action': '' };
    this.form = this.createElement('form', this.attrs);
    document.getElementById(divid).appendChild(this.form);

    //fieldset inside form
    this.fieldset = this.createElement('fieldset');
    this.form.appendChild(this.fieldset);

    //label inside fieldset
    this.attrs = { 'for': 'select-' + divid };
    this.label = this.createElement('label', this.attrs);
    this.fieldset.appendChild(this.label);

    //span inside label containing label text
    this.attrs = { 'text': label };
    this.span = this.createElement('span', this.attrs);
    this.label.appendChild(this.span);

    //select inside label
    this.attrs = { 'id': 'select-' + divid };
    this.select = this.createElement('select', this.attrs);
    this.label.appendChild(this.select);

    //create a global [within this scope] reference to 'this'
    var self = this;

    //bind onchange handler
    this.select.onchange = function () {
			
        //run through classnames array
        this.classLen = self.classes.length;
        for (var i = 0; i < this.classLen; i++) {
            //remove this key (custom class name) from string
            switcher.string = switcher.string.replace(' ' + self.classes[i] + ' ', '');
        }

        //get new value from option
        this.chosen = this.options[this.options.selectedIndex].value;

        //if it isn't default then add to string
        //we need both a leading and a trailing space to work with 
        //to avoid confusion with identical leading or trailing substrings in classnames,
        //such as "high" and "highcontrast" or "large-serif" and "small-serif"
        if (this.chosen != 'default') {
            switcher.string += ' ' + this.chosen + ' ';	
        }

        //set new body class name
        switcher.body.className = switcher.initial + switcher.string;

        //store changes to a cookie which expires a year from now
        switcher.set(365)

        //*** dev
        //document.title = '<' + switcher.body.className.replace(/ /g,'+') + '>   [' + switcher.string.replace(/ /g,'+') + ']';

    };

};

//add a new class option method
bodySwitcher.prototype.defineClass = function (key, val) {
    //option inside select
    this.attrs = { 'value': key, 'text': val };
    this.option = this.createElement('option', this.attrs);
    this.select.appendChild(this.option);

    //check for cookie value 
    if (switcher.cookie != null) {
        //if value contains this key
        if (switcher.cookie.indexOf(' ' + key + ' ') != -1) {
            //select this option
            this.select.selectedIndex = this.options;
        }
    }

    //store the classname 
    this.classes[this.options] = key;

    //increase option count
    this.options++;

};

//create element and attributes method -- http://www.codingforums.com/showthread.php?s=&postid=151108
bodySwitcher.prototype.createElement = function (tag, attrs) {
    //detect support for namespaced element creation, in case we're in the XML DOM
    this.ele = (typeof document.createElementNS != 'undefined') ? document.createElementNS('http://www.w3.org/1999/xhtml', tag) : document.createElement(tag);

    //run through attributes argument
    if (typeof attrs != 'undefined') {
        for (var i in attrs) {
            switch (i) {
                //create a text node 
                case 'text':
                    this.ele.appendChild(document.createTextNode(attrs[i]));
                    break;

                //create a class name 
                case 'class':
                    this.ele.className = attrs[i];
                    break;

                //create a for attribute  
                case 'for':
                    this.ele.setAttribute('htmlFor', attrs[i]);
                    break;

                //create a generic attribute using IE-safe attribute creation 
                default:
                    this.ele.setAttribute(i, '');
                    this.ele[i] = attrs[i];
                    break;
            }
        }
    }
    return this.ele;
};

