/*
 * JavaScript for the Clinique SSFM Quiz.
 * Requires prototype framework version 1.6.0.3
 * Requires scriptaculous library version 1.8.2
 *
 * Built by Control Option
 */


/**
 * Create SSFM namespace to avoid conflicts with other JS libs
 */
var SSFM = {};


/**
 * Add utility methods to SSFM namespace
 */
SSFM.genUID = (function()
{
    var id = 0;
    return function(id_base)
    {
        if(typeof id_base === 'string')
        {
            id_base += "_";
        }
        else
        {
            id_base = '';
        }
        for(var i = 6; --i > 0;)
        {
            id_base += Math.floor(10 + (Math.random() * 6)).toString(16).toUpperCase();
        }
        return id_base + "_" + id++;
    }
})();


SSFM.checkImg = function(element)
{
    var img = $(element);
    var isImg = element.tagName.toUpperCase() === "IMG";
    var isInput = (element.tagName.toUpperCase() === "INPUT" &&
                   element.readAttribute('type').toUpperCase() === "IMAGE");

    if(!(img && (isImg || isInput)))
    {
        img = null;
    }

    return img;
}


SSFM.getQueryString = function ()
{
    var queryString = location.search.substring(1);
    return queryString;
};

SSFM.getQueryArgs = function()
{
    var args = $H(new Object());
    var query = this.getQueryString();
    var pairs = $A(query.split("&"));

    pairs.each(function (pair)
    {
        var eqPos = pair.indexOf("=");
        var argName = pair.substring(0, eqPos);
        var value = pair.substring(eqPos + 1);
        value = decodeURIComponent(value);
        args[argName] = value;
    });

    return args;
};

SSFM.getQueryArgValue = function (argName)
{
    var args = this.getQueryArgs();
    return args[argName];
};


//Image Swap classes start

SSFM.ImgSwap = Class.create({
    initialize: function()
    {
        var images = {};

        function addImg(image, config)
        {
            if((image = SSFM.checkImg(image)))
            {
                if(! config || ! config.constructor === SSFM.ImgSwapConfig)
                {
                    config = new SSFM.ImgSwapConfig();
                }
                else
                {
                    config = config.clone();
                }

                var id = (image.hasAttribute('id')) ? image.readAttribute('id') : image.writeAttribute('id',
                        SSFM.genUID('imgswap')).readAttribute('id');
                image.setStyle({cursor: 'pointer'});

                images[id] = {};
                images[id].elem = image;
                images[id].offImg = new Image();
                images[id].offImg.src = image.src;
                images[id].overImg = new Image();
                images[id].overImg.src = image.src.replace(config.offImgSuffix, config.overImgSuffix);
                if(config.onImgSuffix)
                {
                    images[id].onImg = new Image();
                    images[id].onImg.src = image.src.replace(config.offImgSuffix, config.onImgSuffix);
                }

                config = null;
            }

        }

        function removeImg(image)
        {
            if((image = SSFM.checkImg(image)) && (image.hasAttribute('id')))
            {
                var id = image.readAttribute('id');
                if(images[id])
                {
                    images[id] = null;
                }
            }
        }

        function setOver(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(images[id])
            {
                element.src = images[id].overImg.src;
            }
        }

        function setOff(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(images[id])
            {
                element.src = images[id].offImg.src;
            }
        }

        function setOn(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(images[id] && images[id].onImg)
            {
                element.src = images[id].onImg.src;
            }
        }

        function destroy()
        {
            images = new Object();
            images = null;
        }

        this.addImage = addImg;
        this.removeImage = removeImg;
        this.setOver = setOver;
        this.setOff = setOff;
        this.setOn = setOn;
        this.destroy = destroy;
    }
});

SSFM.ImgSwapConfig = Class.create({
    initialize: function()
    {
        this.offImgSuffix = '_off';
        this.overImgSuffix = '_over';
        this.onImgSuffix = null;
    },

    clone: function ()
    {
        var clone = new SSFM.ImgSwapConfig();
        clone.offImgSuffix = this.offImgSuffix;
        clone.overImgSuffix = this.overImgSuffix;
        clone.onImgSuffix = this.onImgSuffix;
        return clone;
    }
});


SSFM.ImgRolloverHandlers = Class.create({
    initialize: function (imgSwap, indicatorClass, disabledClass)
    {
        if(imgSwap.constructor !== SSFM.ImgSwap)
        {
            return;
        }
        this.imgSwap = imgSwap;
        var indicator = indicatorClass || 'ssfm_rollover';
        this.getIndicator = function ()
        {
            return indicator;
        }

        var disabled = disabledClass || 'disabled';
        this.getDisabledClass = function ()
        {
            return disabled;
        }

        function destroy()
        {
            this.stopObserving();
            imgSwap = null;
            this.boundOver = null;
            this.boundOut = null;
        }

        this.boundOver = this.over.bindAsEventListener(this);
        this.boundOut = this.out.bindAsEventListener(this);

        this.destroy = destroy;
    },

    startObserving: function (observedElement)
    {
        this.stopObserving();
        var observed = (observedElement) ? observedElement : (this.getObserved && this.getObserved()) ?
                                                                this.getObserved() : document;

        this.getObserved = function ()
        {
            return observed;
        }

        Event.observe(observed, 'mouseover', this.boundOver);
        Event.observe(observed, 'mouseout', this.boundOut);
    },

    stopObserving: function ()
    {
        var observed;
        if(this.getObserved)
        {
            observed = this.getObserved();
        }

        if(!observed)
        {
            return;
        }

        Event.stopObserving(observed, 'mouseover', this.boundOver);
        Event.stopObserving(observed, 'mouseout', this.boundOut);
    },

    checkElem: function (element)
    {
        if(! (element = $(element)) || ! (element.hasClassName(this.getIndicator())) ||
           element.hasClassName(this.getDisabledClass()))
        {
            return false;
        }

        return true;
    },

    over: function (event)
    {
        var element = $(Event.findElement(event));
        if(this.checkElem(element))
        {
            this.imgSwap.setOver(element);
        }
    },

    out: function (event)
    {
        var element = $(Event.findElement(event));
        if(this.checkElem(element))
        {
            this.imgSwap.setOff(element);
        }
    }
});

//Image Swap classes end




/*
 *
 */

//Toggle Button classes start
SSFM.ToggleButtons = Class.create({
    initialize: function()
    {
        var buttons = {};

        //Private methods
        function addImg(image, config)
        {
            //console.log("Toggle add Image");
            if((image = SSFM.checkImg(image)))
            {
                if(! config || ! config.constructor === SSFM.ToggleButtonConfig)
                {
                    config = new SSFM.ToggleButtonConfig();
                }
                else
                {
                    config = config.clone();
                }

                var id = (image.hasAttribute('id')) ? image.readAttribute('id') : image.writeAttribute('id',
                        SSFM.genUID('togglebtn')).readAttribute('id');
                image.setStyle({cursor: 'pointer'});

                buttons[id] = {};
                buttons[id].elem = image;
                buttons[id].isOn = false;
                buttons[id].offImg = new Image();
                buttons[id].offImg.src = image.src;
                if(config.overImgSuffix)
                {
                    buttons[id].overImg = new Image();
                    buttons[id].overImg.src = image.src.replace(config.offImgSuffix, config.overImgSuffix);
                }

                buttons[id].onImg = new Image();
                buttons[id].onImg.src = image.src.replace(config.offImgSuffix, config.onImgSuffix);

                config = null;
            }

        }

        function removeImg(image)
        {
            if((image = SSFM.checkImg(image)) && (image.hasAttribute('id')))
            {
                var id = image.readAttribute('id');
                if(buttons[id])
                {
                    buttons[id] = null;
                }
            }
        }

        function setOver(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id] && buttons[id].overImg && !(buttons[id].isOn))
            {
                element.src = buttons[id].overImg.src;
            }
        }

        function setOff(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id] && !(buttons[id].isOn))
            {
                element.src = buttons[id].offImg.src;
            }
        }

        function setToggle(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id])
            {
                if(buttons[id].isOn)
                {
                    buttons[id].isOn = false;
                    element.src = buttons[id].offImg.src;
                }
                else
                {
                    buttons[id].isOn = true;
                    element.src = buttons[id].onImg.src;
                }

                element.fire('togglebutton:toggled', {isOn: buttons[id].isOn});

            }
        }

        function getToggle(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return false;
            }

            var id = element.readAttribute('id');

            if(buttons[id])
            {
                return buttons[id].isOn;
            }
        }

        function destroy()
        {
            buttons = new Object();
            buttons = null;
        }

        this.addImage = addImg;
        this.removeImage = removeImg;
        this.setOver = setOver;
        this.setOff = setOff;
        this.setToggle = setToggle;
        this.getToggle = getToggle;
        this.destroy = destroy;
    }
});


SSFM.ToggleButtonConfig = Class.create({
    initialize: function()
    {
        this.offImgSuffix = '_off';
        this.overImgSuffix = '_over';
        this.onImgSuffix = '_on';
    },

    clone: function ()
    {
        var clone = new SSFM.ToggleButtonConfig();
        clone.offImgSuffix = this.offImgSuffix;
        clone.overImgSuffix = this.overImgSuffix;
        clone.onImgSuffix = this.onImgSuffix;
        return clone;
    }
});


SSFM.ToggleButtonHandlers = Class.create({
    initialize: function (toggles, indicatorClass, disabledClass)
    {
        if(toggles.constructor !== SSFM.ToggleButtons)
        {
            return;
        }

        this.toggles = toggles;
        var indicator = indicatorClass || 'ssfm_toggle';
        this.getIndicator = function ()
        {
            return indicator;
        }

        var disabled = disabledClass || 'disabled';
        this.getDisabledClass = function ()
        {
            return disabled;
        }

        function destroy()
        {
            this.stopObserving();
            toggles = null;
            this.boundOver = null;
            this.boundOut = null;
            this.boundClick = null;
        }

        this.boundOver = this.over.bindAsEventListener(this);
        this.boundOut = this.out.bindAsEventListener(this);
        this.boundClick = this.click.bindAsEventListener(this);

        this.destroy = destroy;
    },

    startObserving: function (observedElement)
    {
        this.stopObserving();
        var observed = (observedElement) ? observedElement : (this.getObserved && this.getObserved()) ?
                                                                this.getObserved() : document;

        this.getObserved = function ()
        {
            return observed;
        }

        Event.observe(observed, 'mouseover', this.boundOver);
        Event.observe(observed, 'mouseout', this.boundOut);
        Event.observe(observed, 'click', this.boundClick);
    },

    stopObserving: function ()
    {
        var observed;
        if(this.getObserved)
        {
            observed = this.getObserved();
        }

        if(!observed)
        {
            return;
        }

        Event.stopObserving(observed, 'mouseover', this.boundOver);
        Event.stopObserving(observed, 'mouseout', this.boundOut);
        Event.stopObserving(observed, 'click', this.boundClick);
    },

    checkElem: function (element)
    {
        if(! (element = $(element)) || ! (element.hasClassName(this.getIndicator())) ||
           element.hasClassName(this.getDisabledClass()))
        {
            return false;
        }

        return true;
    },

    over: function (event)
    {
        var element = $(Event.findElement(event));
        if(this.checkElem(element))
        {
            this.toggles.setOver(element);
        }
    },

    out: function (event)
    {
        var element = $(Event.findElement(event));
        if(this.checkElem(element))
        {
            this.toggles.setOff(element);
        }
    },

    click: function (event)
    {
        var element = $(Event.findElement(event));
        if(this.checkElem(element))
        {
            this.toggles.setToggle(element);
        }
    }
});

//Toggle Button classes end



/*
 *
 */
SSFM.Buttons = Class.create({
    initialize: function()
    {
        var buttons = {};
        var disabledClass = "disabled";
        //Private methods
        function addImg(image, config)
        {
            if((image = SSFM.checkImg(image)))
            {
                if(! config || ! config.constructor === SSFM.ButtonsConfig)
                {
                    config = new SSFM.ButtonsConfig();
                }
                else
                {
                    config = config.clone();
                }

                var id = (image.hasAttribute('id')) ? image.readAttribute('id') : image.writeAttribute('id',
                        SSFM.genUID('imgswap')).readAttribute('id');
                image.setStyle({cursor: 'pointer'});

                buttons[id] = {};
                buttons[id].elem = image;
                buttons[id].isDisabled = false;
                buttons[id].offImg = new Image();
                buttons[id].offImg.src = image.src;
                if(config.overImgSuffix)
                {
                    buttons[id].overImg = new Image();
                    buttons[id].overImg.src = image.src.replace(config.offImgSuffix, config.overImgSuffix);
                }

                buttons[id].disImg = new Image();
                buttons[id].disImg.src = image.src.replace(config.offImgSuffix, config.disabledImgSuffix);


                config = null;
            }

        }

        function removeImg(image)
        {
            if((image = SSFM.checkImg(image)) && (image.hasAttribute('id')))
            {
                var id = image.readAttribute('id');
                if(buttons[id])
                {
                    buttons[id] = null;
                }
            }
        }

        function setOver(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id] && buttons[id].overImg && !(buttons[id].isDisabled))
            {
                element.src = buttons[id].overImg.src;
            }
        }

        function setOff(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id] && !(buttons[id].isDisabled))
            {
                element.src = buttons[id].offImg.src;
            }
        }

        function enable(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id])
            {
                if(buttons[id].isDisabled)
                {
                    buttons[id].isDisabled = false;
                    element.src = buttons[id].offImg.src;
                    element.setStyle({cursor: 'pointer'});
                    element.removeClassName(disabledClass);
                }

                element.fire('button:enabled', {isDisabled: buttons[id].isDisabled});
            }
        }

        function disable(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return;
            }

            var id = element.readAttribute('id');

            if(buttons[id])
            {
                if(! buttons[id].isDisabled)
                {
                    buttons[id].isDisabled = true;
                    element.src = buttons[id].disImg.src;
                    element.setStyle({cursor: 'auto'});
                    element.addClassName(disabledClass);
                }

                element.fire('button:disabled', {isDisabled: buttons[id].isDisabled});
            }
        }

        function isDisabled(element)
        {
            if(! (element = SSFM.checkImg(element)) || ! element.hasAttribute('id'))
            {
                return false;
            }

            var id = element.readAttribute('id');

            if(buttons[id])
            {
                return buttons[id].isDisabled;
            }
        }

        function setDisabledClass(className)
        {
            if(typeof className === "string")
            {
                disabledClass = className;
            }
        }

        function getDisabledClass()
        {
            return disabledClass;
        }

        function destroy()
        {
            buttons = new Object();
            buttons = null;
        }

        this.addImage = addImg;
        this.removeImage = removeImg;
        this.setOver = setOver;
        this.setOff = setOff;
        this.enable = enable;
        this.disable = disable;
        this.isDisabled = isDisabled;
        this.setDisabledClass = setDisabledClass;
        this.getDisabledClass = getDisabledClass;
        this.destroy = destroy;
    }
});

SSFM.ButtonsConfig = Class.create({
    initialize: function()
    {
        this.offImgSuffix = '_off';
        this.overImgSuffix = null;
        this.disabledImgSuffix = "_disabled";
    },

    clone: function ()
    {
        var clone = new SSFM.ButtonsConfig();
        clone.offImgSuffix = this.offImgSuffix;
        clone.overImgSuffix = this.overImgSuffix;
        clone.disabledImgSuffix = this.disabledImgSuffix;
        return clone;
    }
});

/*
 *
 */
SSFM.ImgPreloader = Class.create({
    initialize: function()
    {
        var preloaded = false;
        var len, imgCount, loadedCount;

        function load(images)
        {
            if(images.constructor !== Array)
            {
                throw new Error("SSFM.ImgPreloader Constructor requires an array");
                return;
            }

            len = images.length;

            if(len <= 0)
            {
                setLoaded();
                return;
            }

            imgCount = len;
            loadedCount = 0;


            var arrayItem;
            while(--len >= 0)
            {
                arrayItem = images[len];
                var img;
                if(typeof arrayItem === "string")
                {
                    img = new Image();
                    Event.observe(img, 'load', countLoadedImages);
                    img.src = arrayItem;
                }
                else if((arrayItem.tagName.toUpperCase() === "IMG") ||
                        (arrayItem.tagName.toUpperCase() === "INPUT" &&
                         arrayItem.getAttribute('type').toUpperCase() === "IMAGE"))
                {
                    img = new Image();
                    Event.observe(img, 'load', countLoadedImages);
                    img.src = arrayItem.getAttribute('src');
                }
                else
                {
                    imgCount--;
                }
            }
        }

        function countLoadedImages(event)
        {
            loadedCount++;
            if(loadedCount === imgCount)
            {
                setLoaded();
            }
        }

        function setLoaded()
        {
            preloaded = true;
            document.fire("imgpreloader:loaded");
        }

        this.preload = load;
        this.isPreloaded = function()
        {
            return preloaded;
        }
    }
});


/*
 *
 */
SSFM.QuestionPage = Class.create({
    initialize: function(pageElement)
    {
        var pgElem, answersElem, opacityFX, blindFX;
        if(! (pgElem = $(pageElement)))
        {
            throw new Error("SSFM.QuestionPage constructor parameter pageElement = \"" + pageElement +
                            "\" but needs to be a DOM Element or Element Id");
            return;
        }

        if(! (answersElem = pgElem.down('.answers')))
        {
            throw new Error("SSFM.QuestionPage constructor parameter pageElement needs to have an answers element");
            return;
        }

        var id = pgElem.readAttribute('id'), behaviorType;

        var togBtnConfig = new SSFM.ToggleButtonConfig();
        togBtnConfig.overImgSuffix = "_on";

        var isAnswered = false;

        var choices = $A([
        ]);

        var toggles = new SSFM.ToggleButtons();
        var toggleHandler = new SSFM.ToggleButtonHandlers(toggles, 'ssfm_toggle', 'disabled');
        var answers = answersElem.select('img.ssfm_toggle').each(function(toggleBtn)
        {
            toggles.addImage(toggleBtn, togBtnConfig);
            toggleBtn.observe("togglebutton:toggled", onToggle);
        });

        if(answersElem.hasClassName('select_two'))
        {
            behaviorType = 2;
        }
        else if(answersElem.hasClassName('select_three'))
        {
            behaviorType = 3;
        }
        else if(answersElem.hasClassName('select_all'))
        {
            behaviorType = 0;
        }
        else
        {
            behaviorType = 1;
        }

        var superLayerTriggers = pgElem.select('.superLayerTrigger');
        if(superLayerTriggers.length > 0)
        {
            superLayerTriggers.each(function(trig)
            {
                trig.observe('mouseover', showSuperLayer);
                trig.observe('mouseout', hideSuperLayer);
            });


        }

        function onToggle(event)
        {
            var btn = $(event.findElement());
            if(event.memo.isOn === true)
            {
                choices.push(btn);
                if(behaviorType !== 0 && choices.length > behaviorType)
                {
                    toggles.setToggle(choices.first());
                }
            }
            else
            {
                choices.splice(choices.indexOf(btn), 1);
            }

            isAnswered = (choices.length > 0);
            pgElem.fire("answer:toggled", {answered: isAnswered});
        }

        function createAnswerSet()
        {
            var answerSet;
            if(isAnswered)
            {
                answerSet = {};
                answerSet.pageId = id;
                answerSet.answers = [
                ];

                for(var i = 0, len = choices.length; i < len; i++)
                {
                    var btn = choices[i];
                    var answerObj = {answerId: btn.readAttribute('id'), answerIndex: answers.indexOf(btn)}
                    answerSet.answers.push(answerObj);
                }
            }
            return answerSet;
        }

        function transIn()
        {
            pgElem.setOpacity(0);
            pgElem.show();
            opacityFX = new Effect.Opacity(
                    pgElem,
            {
                from: 0.0,
                to: 1.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.5,
                duration: 1.0
            }
                    );

            blindFX = new Effect.BlindDown(
                    answersElem,
            {
                delay: 0.8,
                duration: 0.8,
                afterFinish: onTransIn
            }
                    );
        }

        function onTransIn()
        {
            opacityFX = null;
            blindFX = null;
            pgElem.fire("page:transitionedIn");
        }

        function transOut()
        {
            opacityFX = new Effect.Opacity(
                    pgElem,
            {
                from: 1.0,
                to: 0.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.2,
                duration: 0.5,
                afterFinish: onTransOut
            }
                    );

        }

        function onTransOut()
        {
            pgElem.hide();
            answersElem.hide();
            opacityFX = null;
            blindFX = null;
            pgElem.fire("page:transitionedOut");
        }

        function showSuperLayer(event)
        {
            var element = $(event.findElement());
            if(!(element.hasClassName('superLayerTrigger')))
            {
                return;
            }

            var sLayer = $(element.readAttribute('id') + '_layer');
            if(sLayer)
            {
                sLayer.show();
            }
        }

        function hideSuperLayer(event)
        {
            var element = $(event.findElement());
            if(!(element.hasClassName('superLayerTrigger')))
            {
                return;
            }

            var sLayer = $(element.readAttribute('id') + '_layer');
            if(sLayer)
            {
                sLayer.hide();
            }
        }

        function enableToggles()
        {
            //console.log("Enable Toggles");
            toggleHandler.startObserving();
        }

        function disableToggles()
        {
            //console.log("Disable Toggles");
            toggleHandler.stopObserving();
        }

        function destroy()
        {
            opacityFX = null;
            blindFX = null;

            toggleHandler.destroy();
            toggleHandler = null;
            toggles.destroy();
            toggles = null;
            answersElem = null;
            pgElem = null;
            pageElement = null;
            answers = new Array();
            answers = null;
        }

        this.transitionIn = transIn;

        this.transitionOut = transOut;

        this.getAnswers = createAnswerSet;

        this.isAnswered = function()
        {
            return isAnswered;
        }

        this.getId = function()
        {
            return id;
        }

        this.getPageElement = function()
        {
            return pgElem;
        }

        this.enableToggles = enableToggles;
        this.disableToggles = disableToggles;

        this.destroy = destroy;
    }
});


/*
 *
 */
SSFM.ButtonSet = Class.create({
    initialize: function(buttonsElement)
    {
        var btnElem;
        if(! (btnElem = $(buttonsElement)))
        {
            throw new Error("SSFM.QuestionPage constructor parameter pageElement = \"" + buttonsElement +
                            "\" but needs to be a DOM Element or Element Id");
            return;
        }

        var id = btnElem.readAttribute('id');

        var nextBtn = btnElem.down('img.btn_next');
        var prevBtn = btnElem.down('img.btn_previous');
        var resultsBtn = btnElem.down('img.btn_results');
        var buttons = new SSFM.Buttons();

        btnElem.select('img.ssfm_button').each(function(btn)
        {
            buttons.addImage(btn);
        });

        disableButton();

        function disableButton()
        {
            if(nextBtn)
            {
                buttons.disable(nextBtn);
            }

            if(resultsBtn)
            {
                buttons.disable(resultsBtn);
            }
        }

        function enableButton()
        {
            if(nextBtn)
            {
                buttons.enable(nextBtn);
            }

            if(resultsBtn)
            {
                buttons.enable(resultsBtn);
            }
        }

        function transIn()
        {
            btnElem.show();
            btnElem.fire("buttons:transitionedIn");
        }

        function transOut()
        {
            btnElem.hide();
            btnElem.fire("buttons:transitionedOut");
        }

        function destroy()
        {
            buttons.destroy();
            btnElem = null;
            buttonsElement = null;
        }

        this.transitionIn = transIn;

        this.transitionOut = transOut;

        this.nextBtn = nextBtn;
        this.previousBtn = prevBtn;
        this.resultsBtn = resultsBtn;

        this.getButtonsElement = function()
        {
            return btnElem;
        }

        this.getButtonsDisabledClass = function()
        {
            return buttons.getDisabledClass();
        }
        this.disableButton = disableButton;
        this.enableButton = enableButton;
        this.destroy = destroy;
    }
});


/*
 *
 */
SSFM.QuizForm = Class.create({
    initialize: function(formContainer, pages, pagesContainer, buttons, buttonsContainer)
    {
        var showSkincare = false;
        var showShave = false;
        var showAcne = false;
        var showEyeArea = false;
        var showRedness = false;
        var showDarkSpots = false;
        var hasDarkSpotsRedness = false;

        var pageSets = [
        ];
        pages.each(function(page)
        {
            pageSets.push(new SSFM.QuestionPage(page));
            page.observe("answer:toggled", onAnswerToggled);
            page.observe("page:transitionedIn", onPgIn);
            page.observe("page:transitionedOut", onPgOut);
        });


        var buttonSets = [
        ];
        buttons.each(function(btn)
        {
            buttonSets.push(new SSFM.ButtonSet(btn));
            btn.observe("buttons:transitionedIn", onBtnsIn);
            btn.observe("buttons:transitionedOut", onBtnsOut);
        });

        var currentPg = 0, lastPg;
        var currentBtns = 0, lastBtns;

        var pgOrder = [
        ];
        var answerSets = [
        ];

        pagesContainer.update(pageSets[currentPg].getPageElement());
        buttonsContainer.update(buttonSets[currentBtns].getButtonsElement());

        pageSets[currentPg].transitionIn();
        buttonSets[currentBtns].transitionIn();

        function onAnswerToggled(event)
        {
            var btnSet = buttonSets[currentBtns];
            if(event.memo.answered)
            {
                btnSet.enableButton();
            }
            else
            {
                btnSet.disableButton();
            }
        }

        function observeButtons()
        {
            document.observe('click', onButtonClick);
        }

        function stopObservingButtons()
        {
            document.stopObserving('click', onButtonClick);
        }


        function onButtonClick(event)
        {
            var element = $(event.findElement());

            if(!(element.hasClassName('ssfm_button')) ||
               (element.hasClassName(buttonSets[currentBtns].getButtonsDisabledClass())))
            {
                return;
            }
            if(element.hasClassName('btn_next'))
            {
                processAnswers(pageSets[currentPg].getAnswers());
                goNext();
                return;
            }

            if(element.hasClassName('btn_previous'))
            {
                goPrevious();
                return;
            }

            if(element.hasClassName('btn_results'))
            {
                goResults();
                return;
            }
        }

        function processAnswers(answerSet)
        {
            answerSets.push(answerSet);
            var answers = answerSet.answers, i, len;

            if(answerSet.pageId === "SkincareShave")
            {
                var hasSkincare = false;
                var hasShave = false;
                for(i = 0,len = answers.length; i < len; i++)
                {
                    if(answers[i].answerId === "skincare_answer")
                    {
                        hasSkincare = true;
                    }

                    if(answers[i].answerId === "shave_answer")
                    {
                        hasShave = true;
                    }
                }
                showSkincare = hasSkincare;
                showShave = hasShave;
                return;
            }

            if(answerSet.pageId === "SkincareConcerns")
            {
                var hasAcne = false;
                var hasEye = false;
                var hasDarkSpots = false;
                var hasRedness = false;
                for(i = 0,len = answers.length; i < len; i++)
                {
                    if(answers[i].answerId === "Acne")
                    {
                        hasAcne = true;
                    }
                    if(answers[i].answerId === "EyeArea")
                    {
                        hasEye = true;
                    }
                    if(answers[i].answerId === "DarkSpots")
                    {
                        hasDarkSpots = true;
                    }
                    if(answers[i].answerId === "Redness")
                    {
                        hasRedness = true;
                    }
                }
                showAcne = hasAcne;
                showEyeArea = hasEye;
                showDarkSpots = hasDarkSpots;
                showRedness = hasRedness;
                return;
            }

            if(answerSet.pageId === "SkincareDarkSpots")
            {
                if(answers[0].answerId === "dsyes")
                {
                    hasDarkSpotsRedness = true;
                }
                else
                {
                    hasDarkSpotsRedness = false;
                }
                return;
            }
        }

        function goNext()
        {
            lastPg = currentPg;
            pgOrder.push(lastPg);

            switch(pageSets[lastPg].getId())
            {
                case "SkincareShave":
                {
                    if(showSkincare)
                    {
                        currentPg++;
                    }
                    else if(showShave)
                    {
                        currentPg += 7;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                case "SkincareConcerns":
                {
                    if(showAcne)
                    {
                        currentPg++;
                    }
                    else if(showEyeArea)
                    {
                        currentPg += 2;
                    }
                    else if(showDarkSpots)
                    {
                        currentPg += 3;
                    }
                    else if(showRedness)
                    {
                        currentPg += 5;
                    }
                    else if(showShave)
                    {
                        currentPg += 6;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                case "SkincareAcne":
                {
                    if(showEyeArea)
                    {
                        currentPg++;
                    }
                    else if(showDarkSpots)
                    {
                        currentPg += 2;
                    }
                    else if(showRedness)
                    {
                        currentPg += 4;
                    }
                    else if(showShave)
                    {
                        currentPg += 5;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                case "SkincareEyes":
                {
                    if(showDarkSpots)
                    {
                        currentPg ++;
                    }
                    else if(showRedness)
                    {
                        currentPg += 3;
                    }
                    else if(showShave)
                    {
                        currentPg += 4;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }
                /*
                 case "SkincareEyes2":
                 {
                 if (showDarkSpots)
                 {
                 currentPg ++;
                 }
                 else if (showRedness)
                 {
                 currentPg += 3;
                 }
                 else if (showShave)
                 {
                 currentPg += 4;
                 }
                 else
                 {
                 currentPg = pageSets.length - 1;
                 }
                 break;
                 }
                 */
                case "SkincareDarkSpots":
                {
                    if(hasDarkSpotsRedness)
                    {
                        currentPg += 2;
                    }
                    else if(!hasDarkSpotsRedness)
                    {
                        currentPg ++;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                case "SkincareDarkSpots2":
                {
                    if(showRedness)
                    {
                        currentPg ++;
                    }
                    else if(showShave)
                    {
                        currentPg += 2;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                case "SkincareRedness":
                {
                    if(showShave)
                    {
                        currentPg ++;
                    }
                    else
                    {
                        currentPg = pageSets.length - 1;
                    }
                    break;
                }

                default:
                {
                    currentPg++;
                    break;
                }
            }

            transition();
        }

        function goPrevious()
        {
            lastPg = currentPg;
            currentPg = pgOrder.pop();
            answerSets.pop();
            transition();
        }

        function transition()
        {
            pageSets[lastPg].disableToggles();
            pageSets[currentPg].disableToggles();
            stopObservingButtons();

            if(currentPg >= pageSets.length || currentPg < 0)
            {
                currentPg = 0;
            }

            lastBtns = currentBtns;
            if(currentPg === 0)
            {
                currentBtns = 0;
            }
            else if(currentPg === (pageSets.length - 1))
            {
                currentBtns = (buttonSets.length - 1);
            }
            else
            {
                currentBtns = 1;
            }

            if(pageSets[currentPg].isAnswered())
            {
                buttonSets[currentBtns].enableButton();
            }
            else
            {
                buttonSets[currentBtns].disableButton();
            }

            if(lastBtns !== currentBtns)
            {
                buttonSets[lastBtns].transitionOut();
            }

            pageSets[lastPg].transitionOut();
        }

        function goResults()
        {
            //console.log("Go To Results");
            pageSets[currentPg].disableToggles();
            stopObservingButtons();
            //pgOrder.push(currentPg);
            answerSets.push(pageSets[currentPg].getAnswers());
            var memoObj = {answerSets: answerSets};
            formContainer.fire("form:resultsclicked", memoObj);
        }

        function onPgIn(event)
        {
            pageSets[currentPg].enableToggles();
            observeButtons();
        }

        function onPgOut(event)
        {
            pageSets[lastPg].getPageElement().remove();
            pagesContainer.update(pageSets[currentPg].getPageElement());
            pageSets[currentPg].transitionIn();
        }

        function onBtnsIn(event)
        {

        }

        function onBtnsOut(event)
        {
            buttonSets[lastBtns].getButtonsElement().remove();
            buttonsContainer.update(buttonSets[currentBtns].getButtonsElement());
            buttonSets[currentBtns].transitionIn();
        }

        this.getAnswerSets = function()
        {
            return answerSets;
        }

        this.destroy = function()
        {
            document.stopObserving('click', onButtonClick);
            observeButtons = null;
            stopObservingButtons = null;
            onButtonClick = null;

            for(var i = pageSets.length; --i >= 0;)
            {
                pageSets[i].destroy();
                pageSets[i] = null;
            }

            pageSets = [
            ];

            for(i = buttonSets.length; --i >= 0;)
            {
                buttonSets[i].destroy();
                buttonSets[i] = null;
            }

            buttonSets = [
            ];

            pgOrder = [
            ];

            formContainer = null;
            pages = null;
            pagesContainer = null;
            buttons = null;
            buttonsContainer = null;

        }
    }
});


/*
 *
 */
SSFM.QuizResults = Class.create({
    initialize: function(options)
    {
        console.log("Quiz Results Init");

        var answerSets = options.answerSets;
        var quizContainer = $(options.quizContainer);
        var recsContainer = $(options.recsContainer);
        var buyMod = $(options.buyMod);
//        var addBtnImg = $(options.addBtnImg);
        var addBtnImg = options.addBtnImg;
        var tosMsgSpan = $(options.tosMsgSpan);
        var tosLinkDiv = $(options.tosLinkDiv);
        var addMsgMod = $(options.addMsgMod);
        var buyModsContainer = $(options.buyModsContainer);
        var heads = options.heads;
        var headsContainer = $(options.headsContainer);
        var tables = options.tables;
        var tableContainer = $(options.tableContainer);
        var printHeadsContainer = $(options.printHeadsContainer);
        var printTableContainer = $(options.printTableContainer);

        var tableHeadId, column1Id, column2Id, column3Id, column4Id, head, pHead, col1, pCol1, col2, pCol2, col3,
                pCol3, col4, pCol4, showFX, hideFX, modToShow, modIsShowing, prodData, buyModObj, boundAddListener;
        var skus = [];
        var shoppableSkus = [];
        var unshoppableProds = [];
        var prodIds = [];
        var triggers = {};
//        var bMods = {};
        var quizWidth = quizContainer.getWidth();
        var addAllBtn = $('ssfm_add_all');
        var showModAfterHide = false;

        processAnswers();

        function processAnswers()
        {
            var skinType;
            var skinTypeHalf;
            var skinTypeBDC = "";
            var skinConcerns = [];
            var frequentAcne = false;
            var hasDarkSpotsRedness = false;
            var dailyRedness = false;
            var darkSpots = "";
            var shaveType;
            var shave;
            var shaveConcerns = false;
            var answerSet, answers, j, jLen;

            for(var i = 0, len = answerSets.length; i < len; i++)
            {
                //console.log ("answerSets.length: " + answerSets.length)
                answerSet = answerSets[i];
                answers = answerSet.answers;

                switch(answerSet.pageId)
                {
                    case "SkincareConcerns":
                    {
                        var hasBDC = false, hasLW = false, hasEC = false, hasAcne = false, hasDS = false, answerId;
                        for(var j = 0, jLen = answers.length; j < jLen; j++)
                        {
                            answerId = answers[j].answerId;
                            switch(answerId)
                            {
                                case "BasicDailyCare":
                                {
                                    hasBDC = true;
                                    break;
                                }

                                case "LinesWrinkles":
                                {
                                    hasLW = true;
                                    break;
                                }

                                case "EyeArea":
                                {
                                    hasEC = true;
                                    break;
                                }

                                case "Acne":
                                {
                                    hasAcne = true;
                                    break;
                                }

                                case "DarkSpots":
                                {
                                    hasDS = true;
                                    break;
                                }

                                default:
                                {
                                    break;
                                }

                            }

                            skinConcerns.push(answerId + "_concern");
                        }

                        if(hasBDC)
                        {
                            skinTypeBDC = 'BDC';
                        }

                        if(hasLW && hasEC)
                        {
                            for(j = 0,jLen = skinConcerns.length; j < jLen; j++)
                            {
                                if(skinConcerns[j] === "LinesWrinkles_concern")
                                {
                                    skinConcerns[j] = "LinesWrinklesTwo_concern";
                                    break;
                                }

                            }
                        }

                        if(hasDS && hasAcne)
                        {
                            for(j = 0,jLen = skinConcerns.length; j < jLen; j++)
                            {
                                if(skinConcerns[j] === "Acne_concern")
                                {
                                    skinConcerns[j] = "AcneTwo_concern";
                                    break;
                                }

                            }
                        }

                        if(hasLW || hasAcne)
                        {
                            for(j = 0,jLen = skinConcerns.length; j < jLen; j++)
                            {
                                if(skinConcerns[j] === "ExcessiveDryness_concern")
                                {
                                    skinConcerns.splice(j, 1);
                                    break;
                                }

                            }
                        }

                        if(hasDS)
                        {
                            darkSpots = 'Dark';
                        }

                        break;
                    }

                    case "SkincareAcne":
                    {
                        if(answers[0].answerId === "acne2" || answers[0].answerId === "acne3")
                        {
                            for(var j = 0, jLen = skinConcerns.length; j < jLen; j++)
                            {
                                if((skinConcerns[j] === "Acne_concern") || (skinConcerns[j] === "AcneTwo_concern"))
                                {
                                    skinConcerns.splice(j, 1);
                                }
                                if(skinConcerns[j] === "DarkSpots_concern")
                                {
                                    skinConcerns[j] = "DarkSpotsTwo_concern";
                                }
                            }
                            frequentAcne = true;

                        }
                        break;
                    }

                    case "SkincareRedness":
                    {
                        if(answers[0].answerId === "daily")
                        {
                            skinConcerns = [
                            ];
                            dailyRedness = true;
                        }
                        break;
                    }

                    case "SkincareDarkSpots":
                    {
                        if(answers[0].answerId === "dsyes")
                        {
                            for(var j = 0, jLen = skinConcerns.length; j < jLen; j++)
                            {
                                if((skinConcerns[j] === "DarkSpots_concern") ||
                                   (skinConcerns[j] === "DarkSpotsTwo_concern"))
                                {
                                    skinConcerns[j] = "Redness_concern";
                                }
                            }
                        }
                        break;
                    }

                    case "ShaveType":
                    {
                        shave = 1;
                        if(answers[0].answerId === "shaving_cream")
                        {
                            shaveType = "Cream";
                        }
                        if(answers[0].answerId === "shave_gel")
                        {
                            shaveType = "Gel";
                        }
                        break;
                    }

                    case "ShaveConcerns":
                    {
                        if(answers[0].answerId === "shave_redness")
                        {
                            shaveConcerns = "Healer";
                        }
                        if(answers[0].answerId === "breakouts")
                        {
                            shaveConcerns = "Blemish";
                        }
                        if(answers[0].answerId === "5oclock_shadow")
                        {
                            shaveConcerns = "Beard";
                        }
                        break;
                    }

                    case "Skintype":
                    {
                        skinType = answers[0].answerIndex + 1;
                        skinTypeHalf = Math.round(skinType / 2);

                        break;
                    }

                    default:
                    {
                        break;
                    }
                }

            }

            tableHeadId = "Skintype" + skinType + skinTypeBDC;

            if(dailyRedness)
            {
                column1Id = "Redness" + skinTypeHalf;
            }
            else if(frequentAcne)
            {
                column1Id = "FrequentAcne";
            }
            else
            {
                column1Id = "BasicDailyCare" + darkSpots + skinType;
            }

            //console.log("column1Id: " + column1Id);

            if(shave)
            {
                column2Id = "Shave";

                if((!frequentAcne) && (!dailyRedness))
                {
                    column2Id += "Scrub";
                }

                if(shaveType)
                {
                    column2Id += shaveType;
                }

                if(shaveConcerns)
                {
                    column2Id += shaveConcerns;
                }

                //console.log("column2Id: " + column2Id);
            }

            if(skinConcerns.length > 0)
            {
                //useSpacer = true;
                column3Id = skinConcerns[0];
                if(skinConcerns[1])
                {
                    column4Id = skinConcerns[1];

                }

            }

            setElements();
        }

        function setElements()
        {
            heads.each(function(h)
            {
                if(h.readAttribute('id') === tableHeadId)
                {
                    head = h;
                    pHead = h.cloneNode(true);
                    //console.log("print head: " + pHead.readAttribute('id'));
                    headsContainer.update(head);
                    printHeadsContainer.update(pHead);
                    throw $break;
                }
            });

            tables.select(
                    function(table)
                    {
                        if(table.hasClassName('columnBDC'))
                        {
                            return table;
                        }
                    }).each(function(col)
            {
                if(col.readAttribute('id') === column1Id)
                {
                    col1 = col;
                    pCol1 = col.cloneNode(true);
                    tableContainer.update(col1);
                    printTableContainer.update(pCol1);
                    createTriggers(col1);
                    throw $break;
                }
            });

            if(column2Id)
            {
                tables.select(
                        function(table)
                        {
                            if(table.hasClassName('columnShave'))
                            {
                                return table;
                            }
                        }).each(function(col)
                {
                    if(col.readAttribute('id') === column2Id)
                    {
                        col2 = col;
                        pCol2 = col.cloneNode(true);
                        tableContainer.insert({bottom: col2});
                        printTableContainer.insert({bottom: pCol2});
                        createTriggers(col2);
                        throw $break;
                    }
                });
            }

            if(column3Id)
            {

                var columnConcerns = tables.select(function(table)
                {
                    if(table.hasClassName('columnConcerns'))
                    {
                        return table;
                    }
                });

                columnConcerns.each(function(col)
                {
                    if(col.readAttribute('id') === column3Id)
                    {
                        col3 = col;
                        pCol3 = col.cloneNode(true);
                        tableContainer.insert({bottom: col3});
                        printTableContainer.insert({bottom: pCol3});
                        createTriggers(col3);
                        throw $break;
                    }
                });


                if(column4Id)
                {
                    columnConcerns.each(function(col)
                    {
                        if(col.readAttribute('id') === column4Id)
                        {
                            col4 = col;
                            pCol4 = col.cloneNode(true);
                            tableContainer.insert({bottom: col4});
                            printTableContainer.insert({bottom: pCol4});
                            createTriggers(col4);
                            throw $break;
                        }
                    });
                }
            }

            if(!col2 && !col3 && !col4)
            {
                var spacer = tables.detect(function(table)
                {
                    return table.hasClassName('columnConcernsSpacer');
                });
                var pSpacer = spacer.cloneNode(true);
                tableContainer.insert({bottom: spacer});
                printTableContainer.insert({bottom: pSpacer});
            }

            getProductData();
        }

        function createTriggers(column)
        {
            var hasProdId = false, id, prodId;
            column.select('li.buyModTrigger').each(function(element)
            {
                //console.log("Create Trigger LI")
                id = element.readAttribute('id');
                triggers[id] = createTriggerObject(id);
                prodId = triggers[id].prod;
                for(var i = prodIds.length; i >= 0; --i)
                {
                    if(prodIds[i] === prodId)
                    {
                        hasProdId = true;
                        break;
                    }
                }
                if(! hasProdId)
                {
                    prodIds.push(prodId);
                }
            });

            column.select('area.buyModTrigger').each(function(element)
            {
                id = element.readAttribute('id');
                triggers[id] = createTriggerObject(id);
            });
        }

        function createTriggerObject(id)
        {
            var prodId = findProd(id);
            console.log("createTriggerObject - prodId: " + prodId);
            //var sku = findSku(id);
            return {prod: prodId/*, sku: sku*/};
        }

        function findProd(id)
        {
            var pattern = /PROD[A-Za-z0-9]+/;
            return id.match(pattern)[0];

        }

        function findSku(id)
        {
            var pattern = /SKU[A-Za-z0-9]+/;
            return id.match(pattern)[0] || null;

        }

        function getProductData()
        {
            console.log("getProductData - prodIds.length: " + prodIds.length);
            var params = [
                {
                    products : prodIds,
                    product_fields : [
                        "PRODUCT_ID", "PROD_RGN_NAME", "PROD_RGN_SUBHEADING", "SUB_LINE", "DESCRIPTION",
                        "SHORT_DESC", "skus", "shaded", "sized", "url"
                    ],
                    sku_fields : [
                        "SKU_ID", "SKU_BASE_ID", "PRODUCT_ID", "formattedPrice",
                        "formattedTaxedPrice", "INVENTORY_STATUS", "isShoppable",
                        "formattedUnitPrice"
                    ]
                }
            ];

            jsonRpcWrapper.fetch({
                method : "prodcat",
                params : params,
                onSuccess: function (jsonRpcResponse)
                {
                    var responseValue = jsonRpcResponse.getValue();
                    processProducts(responseValue);
                },
                onError: function (jsonRpcResponse)
                {
                    console.log(jsonRpcResponse.getMessages());
                }
            });
        }

        function processProducts(data)
        {
            console.log("processProducts: " + data);
            prodData = {};
            var prodsArray = data.products;
            for(var i = 0, length = prodsArray.length; i < length; i++)
            {
                var prod = prodsArray[i];
                var pId = prod.PRODUCT_ID;
                var sku = prod.skus[0];

                console.log("prodId: " + pId);

                if(!sku || sku.isShoppable == 0)
                {
                    unshoppableProds.push(prod);
                }
                else
                {
                    shoppableSkus.push(sku.SKU_BASE_ID);
                }

                prodData[pId] = {};
                prodData[pId].product = prod;
                prodData[pId].sku = sku;
            }

            finish();
        }


        function addToBag(event, skuBaseId)
        {
            event.stop();
            var elem = event.findElement();

            $(elem).stopObserving('click', boundAddListener);

            addAllBtn.stopObserving('click', addAllToBag);

            //transaction.add(skuBaseId, {success: onAddSuccess, failure: onAddFailure});
            
            item_params = {
                skus: [skuBaseId],
                itemType: 'cart',
                INCREMENT: 1
            }
            
            generic.checkout.cart.updateCart({
	            params: item_params,
	            onSuccess: onAddSuccess,
	            onFailure: onAddFailure
	        });

            hideBuyMod();
        }

        function addAllToBag(event)
        {
            if(shoppableSkus.length == 0)
            {
                return;
            }
            
            addAllBtn.stopObserving('click', addAllToBag);
            for(var i = 0, length = shoppableSkus.length; i < length; i++)
            {
                var callbacks;
                if(i == length -1)
                {
                    callbacks = {success: onAddAllSuccess, failure: onAddFailure};
                }

                //transaction.add(shoppableSkus[i], callbacks);
                item_params = {
	                skus: [shoppableSkus[i]],
	                itemType: 'cart',
	                INCREMENT: 1
	            }
	            
	            generic.checkout.cart.updateCart({
		            params: item_params,
		            onSuccess: onAddAllSuccess,
		            onFailure: onAddFailure
		        });
            }
            
        }

        function onAddSuccess()
        {
            console.log("Added to bag");
            showAddMsgMod("single");
        }

        function onAddAllSuccess()
        {
            console.log("Add To Bag Success");
            showAddMsgMod("multi");
        }

        function onAddFailure()
        {
            console.log("Add To Bag Failure");
        }

        function onCloseClick(event)
        {
            var element = $(event.findElement());
            if(element.hasClassName('ssfm_close'))
            {
                modToShow = null;
                var bMod = element.up('.buyMod');
                hideBuyMod();
            }
        }

        function onTriggerClick(event)
        {
            if(hideFX)
            {
                return;
            }
            var element = $(event.findElement());
            if(element.hasClassName('buyModTrigger'))
            {
                var trigProdId = triggers[element.readAttribute('id')].prod;
                console.log("trigProdId: " + trigProdId);
                buyModObj = {};
                buyModObj.prodData = prodData[trigProdId];
                buyModObj.trigger = element;
                modTrans();
            }
        }

        function modTrans()
        {
            if(modIsShowing)
            {
                showModAfterHide = true;
                hideBuyMod();
            }
            else
            {
                showBuyMod();
            }
        }

        function showBuyMod()
        {
            if(!buyMod)
            {
                return;
            }
            var prodObj = buyModObj.prodData;
            var modTrigger = buyModObj.trigger;
            modIsShowing = true;
            buyMod.select('p.altLink').each(function(elem)
            {
                elem.hide();
                if(elem.readAttribute("id") === "altLink_" + prodObj.product.PRODUCT_ID)
                {
                    elem.show();
                }
            });

            buyMod.down('h1.prodName').update(prodObj.product.PROD_RGN_NAME);
            buyMod.down('p.description').update(prodObj.product.DESCRIPTION);
            var priceAddDiv = buyMod.down('div.priceAdd'), spanTag;
            priceAddDiv.update();
            spanTag = new Element('span').update(prodObj.sku.formattedPrice);
            if(prodObj.sku.isShoppable === 0)
            {
                tosLinkDiv.down("a.tos_link").writeAttribute('href', prodObj.product.url);
                priceAddDiv.insert({
                    top: spanTag,
                    bottom: tosMsgSpan
                }).insert({bottom: tosLinkDiv});
            }
            else
            {
                boundAddListener = addToBag.bindAsEventListener(this, prodObj.sku.SKU_BASE_ID);
//                var aTag = new Element('a', {class: 'tos_a_tag', href: '#'}).update(addBtnImg);
                var aTag = new Element('a');
                aTag.writeAttribute('href', 'javascript:void(0);');
                aTag.writeAttribute('class', 'tos_a_tag');
                aTag.update(addBtnImg);
                aTag.observe('click', boundAddListener);

                priceAddDiv.insert({
                    top: spanTag,
                    bottom: aTag
                });
            }


            buyModsContainer.update(buyMod);


            var col = modTrigger.up('div.results_column');
            var colXPos = col.positionedOffset()[0];
            var colWidth = col.getWidth();
            var bModWidth = buyMod.getWidth();
            var bModXPos = colXPos + colWidth;
            if((bModXPos + bModWidth) >= quizWidth)
            {
                bModXPos = colXPos - bModWidth;
            }

            //console.log('buy mod x pos: ' + bModXPos);

            buyMod.setStyle({left: bModXPos + 'px'});
            buyMod.setOpacity(0);
            buyMod.show();
            showFX = new Effect.Opacity(buyMod, {
                from: 0.0,
                to: 1.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.2,
                duration: 0.7,
                afterFinish: onBuyModShow
            });
        }

        function hideBuyMod()
        {
            if(buyMod.getStyle('display') === 'none')
            {
                return;
            }
            if(showFX)
            {
                showFX.cancel();
                showFX = null;
            }
            hideFX = new Effect.Opacity(buyMod, {
                from: 1.0,
                to: 0.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.1,
                duration: 0.4,
                afterFinish: onBuyModHide
            });
        }

        function onBuyModShow()
        {
            //var mod = showFX.element;
            showFX = null;
        }

        function onBuyModHide()
        {
            var mod = hideFX.element;
            mod.hide();
            if(mod.parentNode)
            {
                mod.remove();
            }
            hideFX = null;
            modIsShowing = false;
            if(showModAfterHide)
            {
                showModAfterHide = false;
                showBuyMod();
            }
        }

        function showAddMsgMod(type)
        {
            console.log("showAddMsgMod called");
            if(!addMsgMod)
            {
                console.log("addMsgMod doesn't exist");
                return;
            }



            addMsgMod.select('p.description').invoke('hide');

            if (type == "single")
            {
                var prodObj = buyModObj.prodData;
                addMsgMod.down('p.single').show().down('span.prod_name').update(prodObj.product.PROD_RGN_NAME + ' ');
            }
            else
            {
                var p = addMsgMod.down('p.multi');
                var unShopLen = unshoppableProds.length;

                p.show().select('span').invoke('hide');

                if(unShopLen > 0)
                {
                    var span, a;
                    p.down('span.unfortunately').show();
                    p.down('span.out_of_stock').show();
                   // new Element('span').update(new Element('a', {class: 'tos_prod_link', href: unshoppableProds[0].url}).update(unshoppableProds[0].PROD_RGN_NAME))

                    if(unShopLen == 1)
                    {
                        span = new Element('span');
                        a = new Element('a');
                        a.writeAttribute('href', unshoppableProds[0].url);
                        a.writeAttribute('class', 'tos_prod_link');
                        a.writeAttribute('target', '_blank');
                        a.update(unshoppableProds[0].PROD_RGN_NAME);
                        span.update(a);


                        p.down('span.is').show().insert({
                                before: span
                        });
                    }
                    else
                    {
                        var and = p.down('span.and').show();
                        p.down('span.are').show();

                        span = [];
                        a = [];

                        for(var i = 0; i < unShopLen; i++)
                        {
                            span.push(new Element('span'));
                            a.push(new Element('a'));

                            a[i].writeAttribute('href', unshoppableProds[i].url);
                            a[i].writeAttribute('class', 'tos_prod_link');
                            a[i].writeAttribute('target', '_blank');
                            a[i].update(unshoppableProds[i].PROD_RGN_NAME);

                            span[i].update(a[i]);

                            if(i <= unShopLen - 3)
                            {
                                span[i].insert({
                                    bottom: ', '
                                });

                                and.insert({
                                    before: span[i]
                                });

                            }
                            else if (i == unShopLen - 2)
                            {
                                and.insert({
                                    before: span[i]
                                });
                            }
                            else
                            {
                                and.insert({
                                    after: span[i]
                                });
                            }
                        }
                    }
                }
            }

            document.observe('click', killAddMsgMod);
            buyModsContainer.update(addMsgMod);

            addMsgMod.setOpacity(0);
            addMsgMod.show();
            new Effect.Opacity(addMsgMod, {
                from: 0.0,
                to: 1.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.2,
                duration: 0.7
            });
        }

        function killAddMsgMod(event)
        {
            document.stopObserving('click', killAddMsgMod);
            addAllBtn.observe('click', addAllToBag);
            if (addMsgMod.parentNode)
            {
                addMsgMod.remove();
            }
        }

        function finish()
        {
            document.observe('click', onTriggerClick);
            document.observe('click', onCloseClick);
            addAllBtn.observe('click', addAllToBag);


            //console.log("Num BuyMods: " + bMods.length);
            recsContainer.fire("quizresults:built");
        }

        // TODO: Update destroy method to remove new objs and arrays!
        function destroy()
        {
            document.stopObserving('click', onTriggerClick);
            document.stopObserving('click', onCloseClick);
            addAllBtn.stopObserving('click', addAllToBag);
            addAllBtn = null;
            hideFX = null;
            showFX = null;

            skus = [];
            triggers = {};
            answerSets = null;
            quizContainer = null;
            recsContainer = null;
            buyMod = null;
            buyModsContainer = null;
            heads = null;
            headsContainer = null;
            tables = null;
            tableContainer = null;
            printHeadsContainer = null;
            printTableContainer = null;
        }

        this.destroy = destroy;
    }


});


SSFM.Quiz = Class.create({
    initialize: function(xmlFilePath)
    {
        //console.log("SSFM.Quiz instantiated!");
        if(typeof xmlFilePath !== "string")
        {
            throw new Error("SSFM.Quiz constructor parameter xmlFilePath = \"" + xmlFilePath +
                            "\" but needs to be a String");
            return;
        }

        var quizContainer, formContainer, pagesContainer, buttonsContainer, recsContainer, buyModsContainer,
                headsContainer, tableContainer, printContainer, printHeadsContainer, printTableContainer;

        if(! (quizContainer = $('ssfmQuiz')))
        {
            console.log("SSFM.Quiz no ssfmQuiz element!");
            throw new Error("Cannot find element 'ssfmQuiz'");
            return;
        }

        if(! (formContainer = $('form')))
        {
            console.log("SSFM.Quiz no form element!");
            throw new Error("Cannot find element 'ssfmQuiz'");
            return;
        }

        if(! (pagesContainer = $('pages')))
        {
            console.log("SSFM.Quiz no pages element!");
            throw new Error("Cannot find element 'pages'");
            return;
        }

        if(! (buttonsContainer = $('buttons')))
        {
            console.log("SSFM.Quiz no buttons element!");
            throw new Error("Cannot find element 'buttons'");
            return;
        }

        if(! (recsContainer = $('recs')))
        {
            console.log("SSFM.Quiz no recs element!");
            throw new Error("Cannot find element 'recs'");
            return;
        }

        if(! (buyModsContainer = $('buyMods')))
        {
            console.log("SSFM.Quiz no buyMods element!");
            throw new Error("Cannot find element 'buyMods'");
            return;
        }

        if(! (headsContainer = $('heads')))
        {
            console.log("SSFM.Quiz no heads element!");
            throw new Error("Cannot find element 'heads'");
            return;
        }

        if(! (tableContainer = $('table')))
        {
            console.log("SSFM.Quiz no table element!");
            throw new Error("Cannot find element 'table'");
            return;
        }

        if(! (printContainer = $('ssfmQuizPrintWrapper')))
        {
            console.log("SSFM.Quiz no ssfmQuizPrintWrapper element!");
            throw new Error("Cannot find element 'ssfmQuizPrintWrapper'");
            return;
        }

        if(! (printHeadsContainer = $('headsPrint')))
        {
            console.log("SSFM.Quiz no headsPrint element!");
            throw new Error("Cannot find element 'headsPrint'");
            return;
        }

        if(! (printTableContainer = $('tablePrint')))
        {
            console.log("SSFM.Quiz no tablePrint element!");
            throw new Error("Cannot find element 'tablePrint'");
            return;
        }

        /*if (! (printContainer = $('print')))
         {
         throw new Error("Cannot find element 'print'");
         return;
         }*/

        var xmlContainer, loader, pages, buttons, buyMod, addBtnImg, tosMsgSpan, tosLinkDiv, addMsgMod, heads,
                tables,
                prints, quizForm, answerSets, results;

        var ajaxCall = new Ajax.Request(xmlFilePath, {method: 'get', onSuccess: onAjaxSuccess,
            onError: onAjaxError});

        function onAjaxSuccess(response)
        {
            xmlContainer = new Element('div').update(response.responseText);

            xmlContainer.select('.container').each(function(c)
            {
                if(c.readAttribute('id') === "pages_container")
                {
                    pages = c.childElements();
                    return;
                }

                if(c.readAttribute('id') === "buttons_container")
                {
                    buttons = c.childElements();
                    return;
                }

                if(c.readAttribute('id') === 'buyMods_container')
                {
                    buyMod = c.down('div.buyMod');
                    addBtnImg = c.down('img.add_btn');
                    tosMsgSpan = c.down('span.tos-message');
                    tosLinkDiv = c.down('div.tos_link');
                    addMsgMod = c.down('div.add_msg_mod');
                    return;
                }

                if(c.readAttribute('id') === 'heads_container')
                {
                    heads = c.childElements();
                    return;
                }

                if(c.readAttribute('id') === 'table_container')
                {
                    tables = c.childElements();
                    return;
                }
            });

            loader = new SSFM.ImgPreloader();
            document.observe("imgpreloader:loaded", onImgsLoaded);
            loader.preload(xmlContainer.select('img.ssfm_preload'));

            ajaxCall = null;


            buildQuiz();
        }

        function onAjaxError(response)
        {

        }

        function onImgsLoaded(event)
        {
            //console.log("loaded event");
            //console.log("is loaded: " + loader.isPreloaded());
            document.stopObserving("imgpreloader:loaded", onImgsLoaded);
            loader = null;
        }

        function buildQuiz()
        {
            formContainer.observe('form:resultsclicked', onFormResults);
            quizForm = new SSFM.QuizForm(formContainer, pages, pagesContainer, buttons, buttonsContainer);
        }

        function onFormResults(event)
        {
            formContainer.stopObserving('form:resultsclicked', onFormResults);
            answerSets = event.memo.answerSets;
            buildResults();
        }

        function buildResults()
        {
            recsContainer.observe('quizresults:built', onQuizResultsBuilt);
            var options = {
                answerSets: answerSets,
                quizContainer: quizContainer,
                recsContainer: recsContainer,
                buyMod: buyMod,
                addBtnImg: addBtnImg,
                tosMsgSpan: tosMsgSpan,
                tosLinkDiv: tosLinkDiv,
                addMsgMod: addMsgMod,
                buyModsContainer: buyModsContainer,
                heads: heads, headsContainer: headsContainer,
                tables: tables,
                tableContainer: tableContainer,
                printHeadsContainer: printHeadsContainer,
                printTableContainer: printTableContainer
            };
            results = new SSFM.QuizResults(options);
        }

        function onQuizResultsBuilt(event)
        {
            //console.log("Quiz Results Built");
            recsContainer.stopObserving('quizresults:built', onQuizResultsBuilt);
            transition();
        }

        function transition()
        {
            //console.log("Trans");
            recsContainer.setOpacity(0);
            recsContainer.show();
            new Effect.Opacity(
                    recsContainer,
            {
                from: 0.0,
                to: 1.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.2,
                duration: 1.0
            }
                    );

            new Effect.Opacity(
                    formContainer,
            {
                from: 1.0,
                to: 0.0,
                transition: Effect.Transitions.sinoidal,
                delay: 0.4,
                duration: 1.0,
                afterFinish: onTrans
            }
                    );
        }

        function onTrans()
        {
            formContainer.hide();
        }

        this.destroy = function()
        {
            recsContainer.stopObserving('quizresults:built', onQuizResultsBuilt);
            formContainer.stopObserving('form:resultsclicked', onFormResults);
            onAjaxSuccess = null;

            if(quizForm)
            {
                quizForm.destroy();
                quizForm = null;
            }

            if(results)
            {
                results.destroy();
                results = null;
            }

            formContainer = null;
            pagesContainer = null;
            buttonsContainer = null;
            recsContainer = null;
            buyModsContainer = null;
            headsContainer = null;
            tableContainer = null;
            printContainer = null;
            printHeadsContainer = null;
            printTableContainer = null;

            //quizContainer.remove();
            quizContainer = null;

            xmlContainer = null;
        }
    }
});


// preload images for first page here
	document.observe("dom:loaded", function(event){
		var pl = new SSFM.ImgPreloader();
		pl.preload(["/images/ssfmQuiz/head_begin.gif","/images/ssfmQuiz/answer_SkincareShave_1_off.gif", "/images/ssfmQuiz/answer_SkincareShave_2_off.gif", "/images/ssfmQuiz/btn_next_disabled.gif"]);
	});
	var ssfm;
	launchSSFMQuiz = function() {
		templatefactory.get('/ssfmQuiz/ssfmQuiz.tmpl').evaluateCallback({
			callback: function (html){
				generic.overlay.launch({
	                content: html,
	                includeCloseLink: 0
	            });
	            $('ssfm_close_link').observe('click', function(){
	                generic.overlay.hide();
	                ssfm.destroy();
					ssfm = null;
	            });
				ssfm = new SSFM.Quiz("/ssfmQuiz/ssfmQuiz.xml");
			}
		});
	};

