// class RoloFlo
function RoloFlo ()
{
	this.defaults =
	{
		RoloFloID:         'roloflo',
		imageCursor:        'default',
		aspect:              1.964,
		height:             0.67,
		depth:              4, 
		multiplier:         1.0,  
		multiplierSelected: 1.0, 
 		scaling:            true,
		scaleLandscape:     130,  
		scale:              100,  
		bar:                true,
		barGrip:            'e-resize',
		barWidth:           22,   
		scrollWidth:        0.6,
		defaultImage:            1,
		autoStart:     false,
		mirrorGet:      '',
		mirrorDepth:        0.5,
		mirrorType:      false,
		reflections:        true,
		opacity:            false,
		opacities:          [10,8,6,4,2],
		stepWidth:              150,
		showNavbuttons:        false,
		showLabels:           false,
                preload:      true,
		onClick:            function() {window.open(this.url,'newwindow','width=600,height=600') }
	};

	var thisObject = this;

	this.init = function (options)
        {
            var optionsArray = ['aspect', 'showNavbuttons', 'showLabels', 'imageCursor', 'multiplier', 'RoloFloID', 'multiplierSelected', 'depth', 'height', 'onClick', 'opacity', 'opacities', 'scaleLandscape', 'scale', 'preload', 'reflections', 'mirrorGet', 'mirrorDepth', 'mirrorType','scaling', 'scrollWidth', 'bar', 'barGrip', 'barWidth', 'defaultImage', 'autoStart', 'stepWidth'];
            var max = optionsArray.length;
            for (var i = 0; i < max; i++)
            {
                var name = optionsArray[i];
                this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : thisObject.defaults[name];
            }

            var RoloFloDiv = document.getElementById(thisObject.RoloFloID);
            if(RoloFloDiv)
            {
                RoloFloDiv.style.visibility = 'visible';
                this.RoloFloDiv = RoloFloDiv;

                if(this.createStructure())
                {
                    this.imagesDiv = document.getElementById(thisObject.RoloFloID+'_images');
                    this.captionDiv = document.getElementById(thisObject.RoloFloID+'_caption');
                    this.navigationDiv = document.getElementById(thisObject.RoloFloID+'_navigation');
                    this.scrollbarDiv = document.getElementById(thisObject.RoloFloID+'_scrollbar');
                    this.sliderDiv = document.getElementById(thisObject.RoloFloID+'_slider');
                    this.buttonNextDiv = document.getElementById(thisObject.RoloFloID+'_next');
                    this.buttonPreviousDiv = document.getElementById(thisObject.RoloFloID+'_previous');

                    this.indexArray = [];
                    this.current = 0;
                    this.imageID = 0;
                    this.target = 0;
                    this.memTarget = 0;
                    this.firstRefresh = true;
                    this.firstCheck = true;
                    this.busy = false;

                    if(this.bar === false)
                        this.scrollbarDiv.style.display = 'none';

                    var width = this.RoloFloDiv.offsetWidth;
                    var height = Math.round(width / thisObject.aspect);
                    document.getElementById(thisObject.RoloFloID+'_loading_txt').style.paddingTop = ((height * 0.5) -22) + 'px';
                    RoloFloDiv.style.height = height + 'px';
                    this.loadingProgress();
                }
            }
	};
	
	this.createStructure = function()
	{
            var imagesDiv = thisObject.Helper.createDocumentElement('div','images');

            var node = null;
            var max = this.RoloFloDiv.childNodes.length;
            for(var index = 0; index < max; index++)
            {
                node = this.RoloFloDiv.childNodes[index];
                if (node && node.nodeType == 1 && node.nodeName == 'IMG')
                {
                    if(thisObject.reflections === true)
                    {
                        var version = '2';
                        if(thisObject.mirrorType === true)
                        {
                            version = '3';
                        }
                        var src = node.getAttribute('src',2);
                        src =  'reflect'+version+'.php?img='+src+thisObject.mirrorGet;
                        node.setAttribute('src',src);
                    }

                    var imageNode = node.cloneNode(true);
                    imagesDiv.appendChild(imageNode);
                }
            }

            var loadingP = thisObject.Helper.createDocumentElement('p','loading_txt');
            var loadingText = document.createTextNode(' ');
            loadingP.appendChild(loadingText);

            var loadingDiv = thisObject.Helper.createDocumentElement('div','loading');

            var loadingBarDiv = thisObject.Helper.createDocumentElement('div','loading_bar');
            loadingDiv.appendChild(loadingBarDiv);

            var captionDiv = thisObject.Helper.createDocumentElement('div','caption');

            var scrollbarDiv = thisObject.Helper.createDocumentElement('div','scrollbar');
            var sliderDiv = thisObject.Helper.createDocumentElement('div','slider');
            scrollbarDiv.appendChild(sliderDiv);
            if(thisObject.showNavbuttons)
            {
                var buttonPreviousDiv = thisObject.Helper.createDocumentElement('div','previous', 'button');
                var buttonNextDiv = thisObject.Helper.createDocumentElement('div','next', 'button');
                scrollbarDiv.appendChild(buttonPreviousDiv);
                scrollbarDiv.appendChild(buttonNextDiv);
            }

            var navigationDiv = thisObject.Helper.createDocumentElement('div','navigation');
            navigationDiv.appendChild(captionDiv);
            navigationDiv.appendChild(scrollbarDiv);

            var success = false;
            if (thisObject.RoloFloDiv.appendChild(imagesDiv) &&
                thisObject.RoloFloDiv.appendChild(loadingP) &&
                thisObject.RoloFloDiv.appendChild(loadingDiv) &&
                thisObject.RoloFloDiv.appendChild(navigationDiv))
            {
                for(index = 0; index < max; index++)
                {
                    node = this.RoloFloDiv.childNodes[index];
                    if (node && node.nodeType == 1 && node.nodeName == 'IMG')
                    {
                        this.RoloFloDiv.removeChild(node);
                    }
                }
                success = true;
            }
            return success;
	};

	
	this.loadingProgress = function()
	{
            var p = thisObject.loadingStatus();
            if(p < 100 || thisObject.firstCheck === true && thisObject.preload === true)
            {
                if(thisObject.firstCheck === true && p == 100)
                {
                    thisObject.firstCheck = false;
                    window.setTimeout(thisObject.loadingProgress, 100);
                }
                else
                {
                    window.setTimeout(thisObject.loadingProgress, 40);
                }
            }
            else
            {
                document.getElementById(thisObject.RoloFloID+'_loading_txt').style.display = 'none';
                document.getElementById(thisObject.RoloFloID+'_loading').style.display = 'none';

                // delay adding this event for the IE
                window.setTimeout(thisObject.Helper.addResizeEvent, 1000);

                thisObject.MouseWheel.init();
                thisObject.MouseDrag.init();
                thisObject.Touch.init();
                thisObject.Key.init();

                thisObject.refresh(true);

                document.getElementById(thisObject.RoloFloID+'_scrollbar').style.visibility = 'visible';

                // glide to image
                var defaultImage = thisObject.defaultImage-1;
                if (defaultImage < 0 )
                    defaultImage = 0;
                if (defaultImage > thisObject.max)
                    defaultImage = thisObject.max -1;
                thisObject.glideTo(defaultImage);

                /// move to image
                if(thisObject.autoStart === true)
                    thisObject.moveTo(5000);

            }
	};

	this.loadingStatus = function()
	{
            var max = thisObject.imagesDiv.childNodes.length;
            var i = 0, completed = 0;
            var image = null;
            for(var index = 0; index < max; index++)
            {
                image = thisObject.imagesDiv.childNodes[index];
                if (image && image.nodeType == 1 && image.nodeName == 'IMG')
                {
                    if (image.complete === true)
                            completed++;

                    i++;
                }
            }
            var finished = Math.round((completed/i)*100);
            var loadingBar = document.getElementById(thisObject.RoloFloID+'_loading_bar');
            loadingBar.style.width = finished+'%';

            var loadingP = document.getElementById(thisObject.RoloFloID+'_loading_txt');
            var loadingTxt = document.createTextNode(completed+' of '+i+' photos loaded');
            loadingP.replaceChild(loadingTxt,loadingP.firstChild);
            return finished;
	};

	
	// Cache all that only changes on refresh or resize of the window 
	this.refresh = function()
	{
            this.imagesDivWidth = thisObject.imagesDiv.offsetWidth+thisObject.imagesDiv.offsetLeft;
            this.maxHeight = Math.round(thisObject.imagesDivWidth / thisObject.aspect);
            this.maxFocus = thisObject.depth * thisObject.stepWidth;
            this.size = thisObject.imagesDivWidth * 0.5;
            this.barWidth = thisObject.barWidth * 0.5;
            this.scrollbarWidth = (thisObject.imagesDivWidth - ( Math.round(thisObject.barWidth) * 2)) * thisObject.scrollWidth;
            this.imagesDivHeight = Math.round(thisObject.maxHeight * thisObject.height);

            thisObject.RoloFloDiv.style.height = thisObject.maxHeight + 'px';

            thisObject.imagesDiv.style.height =  thisObject.imagesDivHeight + 'px';

            thisObject.navigationDiv.style.height =  (thisObject.maxHeight - thisObject.imagesDivHeight) + 'px';

            thisObject.captionDiv.style.width = thisObject.imagesDivWidth + 'px';
            thisObject.captionDiv.style.paddingTop = Math.round(thisObject.imagesDivWidth * 0.02) + 'px';

            thisObject.scrollbarDiv.style.width = thisObject.scrollbarWidth + 'px';
            thisObject.scrollbarDiv.style.marginTop = Math.round(thisObject.imagesDivWidth * 0.02) + 'px';
            thisObject.scrollbarDiv.style.marginLeft = Math.round(thisObject.barWidth + ((thisObject.imagesDivWidth - thisObject.scrollbarWidth)/2)) + 'px';

            thisObject.sliderDiv.style.cursor = thisObject.barGrip;
            thisObject.sliderDiv.onmousedown = function () { thisObject.MouseDrag.start(this); return false;};

            if(thisObject.showNavbuttons)
            {
                    thisObject.buttonPreviousDiv.onclick = function () { thisObject.MouseWheel.handle(1); };
                    thisObject.buttonNextDiv.onclick = function () { thisObject.MouseWheel.handle(-1); };
            }

            // et the reflection multiplier */
            var multi = (thisObject.reflections === true) ? thisObject.mirrorDepth + 1 : 1;

            // set image attributes
            var max = thisObject.imagesDiv.childNodes.length;
            var i = 0;
            var image = null;
            for (var index = 0; index < max; index++)
            {
                image = thisObject.imagesDiv.childNodes[index];
                if(image !== null && image.nodeType == 1 && image.nodeName == 'IMG')
                {
                    this.indexArray[i] = index;

                    // et image attributes to store values
                    image.url = image.getAttribute('longdesc');
                    image.xPosition = (-i * thisObject.stepWidth);
                    image.i = i;

                    // add width and height as attributes only once
                    if(thisObject.firstRefresh)
                    {
                        if(image.getAttribute('width') !== null && image.getAttribute('height') !== null)
                        {
                            image.w = image.getAttribute('width');
                            image.h = image.getAttribute('height') * multi;
                        }
                        else{
                            image.w = image.width;
                            image.h = image.height;
                        }
                    }

                    // check source image format. get image height minus reflection height!
                    if((image.w) > (image.h / (thisObject.mirrorDepth + 1)))
                    {
                        // landscape format
                        image.pc = thisObject.scaleLandscape;
                        image.pcMem = thisObject.scaleLandscape;
                    }
                    else
                    {
                        // portrait and square format
                        image.pc = thisObject.scale;
                        image.pcMem = thisObject.scale;
                    }

                    if(thisObject.scaling === false)
                    {
                        image.style.position = 'relative';
                        image.style.display = 'inline';
                    }

                    image.style.cursor = thisObject.imageCursor;
                    i++;
                }
            }
            this.max = thisObject.indexArray.length;

            // Override dynamic sizes based on the first image
            if(thisObject.scaling === false)
            {
                image = thisObject.imagesDiv.childNodes[thisObject.indexArray[0]];

                // set left padding for the first image
                this.totalImagesWidth = image.w * thisObject.max;
                image.style.paddingLeft = (thisObject.imagesDivWidth/2) + (image.w/2) + 'px';

                // override images and navigation div height
                thisObject.imagesDiv.style.height =  image.h + 'px';
                thisObject.navigationDiv.style.height =  (thisObject.maxHeight - image.h) + 'px';
            }

            if(thisObject.firstRefresh)
                thisObject.firstRefresh = false;

            thisObject.glideTo(thisObject.imageID);
            thisObject.moveTo(thisObject.current);
	};


	// move to anim
	this.moveTo = function(x)
	{
            this.current = x;
            this.zIndex = thisObject.max;

            for (var index = 0; index < thisObject.max; index++)
            {
                var image = thisObject.imagesDiv.childNodes[thisObject.indexArray[index]];
                var currentImage = index * -thisObject.stepWidth;

                if(thisObject.scaling)
                {
                    // no all displayed
                    if ((currentImage + thisObject.maxFocus) < thisObject.memTarget || (currentImage - thisObject.maxFocus) > thisObject.memTarget)
                    {
                        image.style.visibility = 'hidden';
                        image.style.display = 'none';
                    }
                     else
                    {
                        var z = (Math.sqrt(10000 + x * x) + 100) * thisObject.multiplier;
                        var xs = x / z * thisObject.size + thisObject.size;

                        // block whild processed
                        image.style.display = 'block';

                        // calc new image height and image width
                        var newImageH = (image.h / image.w * image.pc) / z * thisObject.size;
                        var newImageW = 0;
                        switch (newImageH > thisObject.maxHeight)
                        {
                            case false:
                                newImageW = image.pc / z * thisObject.size;
                                break;
                            default:
                                newImageH = thisObject.maxHeight;
                                newImageW = image.w * newImageH / image.h;
                                break;
                        }

                        var newImageTop = (thisObject.imagesDivHeight - newImageH) + ((newImageH / (thisObject.mirrorDepth + 1)) * thisObject.mirrorDepth);

                        //new image properties
                        image.style.left = xs - (image.pc / 2) / z * thisObject.size + 'px';
                        if(newImageW && newImageH)
                        {
                            image.style.height = newImageH + 'px';
                            image.style.width = newImageW + 'px';
                            image.style.top = newImageTop + 'px';
                        }
                        image.style.visibility = 'visible';

                        // set  zIndex
                        switch ( x < 0 )
                        {
                            case true:
                                this.zIndex++;
                                break;
                            default:
                                this.zIndex = thisObject.zIndex - 1;
                                break;
                        }

                        // change zIndex and onclick function of the current image
                        switch ( image.i == thisObject.imageID )
                        {
                            case false:
                                image.onclick = function() { thisObject.glideTo(this.i);};
                                break;

                            default:
                                this.zIndex = thisObject.zIndex + 1;
                                if(image.url !== '')
                                {
                                    image.onclick = thisObject.onClick;
                                }
                                break;
                        }
                        image.style.zIndex = thisObject.zIndex;
                    }
                }

                // no scaling
                else
                {
                    if ((currentImage + thisObject.maxFocus) < thisObject.memTarget || (currentImage - thisObject.maxFocus) > thisObject.memTarget)
                    {
                        image.style.visibility = 'hidden';
                    }
                    else
                    {
                        image.style.visibility = 'visible';

                        // set onclick function of the current image
                        switch ( image.i == thisObject.imageID )
                        {
                            case false:
                                image.onclick = function() { thisObject.glideTo(this.i);};
                                break;
                            default:
                                if(image.url !== '')
                                        image.onclick = thisObject.onClick;
                                    
                                break;
                        }
                    }
                    thisObject.imagesDiv.style.marginLeft = (x - thisObject.totalImagesWidth) + 'px';
                }

                x += thisObject.stepWidth;
            }
	};

	
	// init glide
	this.glideTo = function(imageID)
	{
		// new image position target */
		var x = -imageID * thisObject.stepWidth;
		this.target = x;
		this.memTarget = x;
		this.imageID = imageID;

		// new caption
		var caption = thisObject.imagesDiv.childNodes[imageID].getAttribute('alt');
		if (caption === '' || thisObject.showLabels === false)
		{
                    caption = '&nbsp;';
		}
		thisObject.captionDiv.innerHTML = caption;

		// new position
		if (thisObject.MouseDrag.busy === false)
		{
                    this.newSliderX = (imageID * thisObject.scrollbarWidth) / (thisObject.max-1) - thisObject.MouseDrag.newX;
                    thisObject.sliderDiv.style.marginLeft = (thisObject.newSliderX - thisObject.barWidth) + 'px';
		}

		// process if opacity or a multiplicator for the current image has been set
		if(thisObject.opacity === true || thisObject.multiplierSelected !== thisObject.defaults.multiplierSelected)
		{
                    // opacity for centered image
                    thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[imageID], thisObject.opacities[0]);
                    thisObject.imagesDiv.childNodes[imageID].pc = thisObject.imagesDiv.childNodes[imageID].pc * thisObject.multiplierSelected;

                    // opacity for other images
                    var opacityValue = 0;
                    var rightID = 0;
                    var leftID = 0;
                    var last = thisObject.opacities.length;

                    for (var i = 1; i < (thisObject.depth+1); i++)
                    {
                        if((i+1) > last)
                            opacityValue = thisObject.opacities[last-1];
                        else
                            opacityValue = thisObject.opacities[i];

                        rightID = imageID + i;
                        leftID = imageID - i;

                        if (rightID < thisObject.max)
                        {
                            thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[rightID], opacityValue);
                            thisObject.imagesDiv.childNodes[rightID].pc = thisObject.imagesDiv.childNodes[rightID].pcMem;
                        }
                        if (leftID >= 0)
                        {
                            thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[leftID], opacityValue);
                            thisObject.imagesDiv.childNodes[leftID].pc = thisObject.imagesDiv.childNodes[leftID].pcMem;
                        }
                    }
		}

		// Animate to new x position
		if (thisObject.busy === false)
		{
			window.setTimeout(thisObject.animate, 50);
			thisObject.busy = true;
		}
	};


    // glide animation
    this.animate = function()
    {
        switch (thisObject.target < thisObject.current-1 || thisObject.target > thisObject.current+1)
        {
            case true:
                    thisObject.moveTo(thisObject.current + (thisObject.target-thisObject.current)/3);
                    window.setTimeout(thisObject.animate, 50);
                    thisObject.busy = true;
                    break;

            default:
                    thisObject.busy = false;
                    break;
        }
    };
	
	
    this.MouseWheel =
    {
        init: function()
        {
            if(window.addEventListener)
                thisObject.RoloFloDiv.addEventListener('DOMMouseScroll', thisObject.MouseWheel.get, false);
            thisObject.Helper.addEvent(thisObject.RoloFloDiv,'mousewheel',thisObject.MouseWheel.get);
        },

            get: function(event)
            {
                var delta = 0;
                if (!event)
                    event = window.event;

                if (event.wheelDelta)
                    delta = event.wheelDelta / 120;
                else if (event.detail)
                    delta = -event.detail / 3;

                if (delta)
                    thisObject.MouseWheel.handle(delta);

                thisObject.Helper.suppressBrowserDefault(event);
            },

            handle: function(delta)
            {
                var change = false;
                var newImageID = 0;
                if(delta > 0)
                {
                    if(thisObject.imageID >= 1)
                    {
                        newImageID = thisObject.imageID -1;
                        change = true;
                    }
                }
                else
                {
                    if(thisObject.imageID < (thisObject.max-1))
                    {
                        newImageID = thisObject.imageID +1;
                        change = true;
                    }
                }

                if (change === true)
                {
                    thisObject.glideTo(newImageID);
                }
            }
    };


    this.MouseDrag =
    {
            object: null,
            objectX: 0,
            mouseX: 0,
            newX: 0,
            busy: false,

            init: function()
            {
                thisObject.Helper.addEvent(thisObject.RoloFloDiv,'mousemove',thisObject.MouseDrag.drag);
                thisObject.Helper.addEvent(thisObject.RoloFloDiv,'mouseup',thisObject.MouseDrag.stop);
                thisObject.Helper.addEvent(document,'mouseup',thisObject.MouseDrag.stop);

                // void text and image selection while dragging
                thisObject.RoloFloDiv.onselectstart = function ()
                {
                    var selection = true;
                    if (thisObject.MouseDrag.busy === true)
                        selection = false;

                    return selection;
                };
            },

            start: function(o)
            {
                thisObject.MouseDrag.object = o;
                thisObject.MouseDrag.objectX = thisObject.MouseDrag.mouseX - o.offsetLeft + thisObject.newSliderX;
            },

            stop: function()
            {
                thisObject.MouseDrag.object = null;
                thisObject.MouseDrag.busy = false;
            },

            drag: function(e)
            {
                var posx = 0;
                if (!e)
                        e = window.event;

                if (e.pageX)
                        posx = e.pageX;
                else if (e.clientX)
                        posx = e.clientX + document.body.scrollLeft	+ document.documentElement.scrollLeft;

                thisObject.MouseDrag.mouseX = posx;

                if(thisObject.MouseDrag.object !== null)
                {
                    var newX = (thisObject.MouseDrag.mouseX - thisObject.MouseDrag.objectX) + thisObject.barWidth;

                    // make sure, that the bar is moved in proper relation to
                    // previous movements by the glideTo function */
                    if(newX < ( - thisObject.newSliderX))
                            newX = - thisObject.newSliderX;
                        
                    if(newX > (thisObject.scrollbarWidth - thisObject.newSliderX))
                            newX = thisObject.scrollbarWidth - thisObject.newSliderX;

                    // new position
                    var step = (newX + thisObject.newSliderX) / (thisObject.scrollbarWidth / (thisObject.max-1));
                    var imageID = Math.round(step);
                    thisObject.MouseDrag.newX = newX;
                    thisObject.MouseDrag.object.style.left = newX + 'px';
                    if(thisObject.imageID !== imageID)
                    {
                            thisObject.glideTo(imageID);
                    }
                    thisObject.MouseDrag.busy = true;
                }
            }
    };


    this.Touch =
    {
            x: 0,
            startX: 0,
            stopX: 0,
            busy: false,
            first: true,

            init: function()
            {
                thisObject.Helper.addEvent(thisObject.navigationDiv,'touchstart',thisObject.Touch.start);
                thisObject.Helper.addEvent(document,'touchmove',thisObject.Touch.handle);
                thisObject.Helper.addEvent(document,'touchend',thisObject.Touch.stop);
            },

            isOnNavigationDiv: function(e)
            {
                var state = false;
                if(e.touches)
                {
                    var target = e.touches[0].target;
                    if(target === thisObject.navigationDiv || target === thisObject.sliderDiv || target === thisObject.scrollbarDiv)
                        state = true;
                }
                return state;
            },

            getX: function(e)
            {
                var x = 0;
                if(e.touches)
                    x = e.touches[0].pageX;
                return x;
            },

            start: function(e)
            {
                thisObject.Touch.startX = thisObject.Touch.getX(e);
                thisObject.Touch.busy = true;
                thisObject.Helper.suppressBrowserDefault(e);
            },

            isBusy: function()
            {
                var busy = false;
                if(thisObject.Touch.busy === true)
                        busy = true;

                return busy;
            },

            // Handle touch event position within the navigation div
            handle: function(e)
            {
                if(thisObject.Touch.isBusy && thisObject.Touch.isOnNavigationDiv(e))
                {
                    if(thisObject.Touch.first)
                    {
                        thisObject.Touch.stopX = ((thisObject.max-1)-thisObject.imageID) * (thisObject.imagesDivWidth / (thisObject.max-1));
                        thisObject.Touch.first = false;
                    }
                    var newX = -(thisObject.Touch.getX(e) - thisObject.Touch.startX - thisObject.Touch.stopX);

                    if(newX < 0)
                        newX = 0;

                    if(newX > thisObject.imagesDivWidth)
                        newX = thisObject.imagesDivWidth;


                    thisObject.Touch.x = newX;

                    var imageID = Math.round(newX / (thisObject.imagesDivWidth / (thisObject.max-1)));
                    imageID = (thisObject.max-1)-imageID;

                    if(thisObject.imageID !== imageID)
                        thisObject.glideTo(imageID);

                    thisObject.Helper.suppressBrowserDefault(e);
                }
            },

        stop: function()
        {
            thisObject.Touch.stopX = thisObject.Touch.x;
            //thisObject.Touch.stopX = -(thisObject.Touch.x - thisObject.imagesDivWidth);

            thisObject.Touch.busy = false;
        }
    };
	

    this.Key =
    {
        // init key event listener
        init: function()
        {
            document.onkeydown = function(event){ thisObject.Key.handle(event); };
        },

        handle: function(event)
        {
            var charCode  = thisObject.Key.get(event);
            switch (charCode)
            {
                /// r arrow key
                case 39:
                    thisObject.MouseWheel.handle(-1);
                    break;

                // l arrow key
                case 37:
                    thisObject.MouseWheel.handle(1);
                    break;
            }
        },

        // get keycode
        get: function(event)
        {
            event = event || window.event;
            return event.keyCode;
        }
    };


    this.Helper =
    {
        addEvent: function(obj, type, fn)
        {
            if(obj.addEventListener)
            {
                obj.addEventListener(type, fn, false);
            }
            else if(obj.attachEvent)
            {
                obj["e"+type+fn] = fn;
                obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
                obj.attachEvent( "on"+type, obj[type+fn] );
            }
        },

        setOpacity: function(object, value)
        {
            if(thisObject.opacity === true)
            {
                object.style.opacity = value/10;
                object.style.filter = 'alpha(opacity=' + value*10 + ')';
            }
        },

        createDocumentElement: function(type, id, optionalClass)
        {
            var element = document.createElement(type);
            element.setAttribute('id',thisObject.RoloFloID+'_'+id);
            if(optionalClass !== undefined)
                id += ' '+optionalClass;

            element.setAttribute('class',id);
            element.setAttribute('className',id);
            return element;
        },

        // avoid image/text selection while dragging
        suppressBrowserDefault: function(e)
        {
            if(e.preventDefault)
                e.preventDefault();
            else
                e.returnValue = false;
            return false;
        },

        addResizeEvent: function()
        {
            var otherFunctions = window.onresize;
            if(typeof window.onresize != 'function')
            {
                window.onresize = function()
                {
                    thisObject.refresh();
                };
            }
            else
            {
                window.onresize = function(){
                    if (otherFunctions)
                    {
                        otherFunctions();
                    }
                    thisObject.refresh();
                };
            }
        }
    };
}

var doOnLoad =
{
    name: "doOnLoad",
    handlers: {},
    domReadyID: 1,
    wasRun: false,
    DOMContentLoadedCustom: null,

    add: function(handler)
    {
        if (!handler.$$domReadyID)
        {
            handler.$$domReadyID = this.domReadyID++;

            if(this.wasRun)
                    handler();

            this.handlers[handler.$$domReadyID] = handler;
        }
    },

    remove: function(handler)
    {
        if (handler.$$domReadyID)
            delete this.handlers[handler.$$domReadyID];
    },

    run: function()
    {
        if (this.wasRun)
            return;

        this.wasRun = true;

        for (var i in this.handlers)
            this.handlers[i]();
    },

    schedule: function()
    {
        if (this.wasRun)
            return true;

        if(/KHTML|WebKit/i.test(navigator.userAgent))
            if(/loaded|complete/.test(document.readyState))
                this.run();
            else
                setTimeout(this.name + ".schedule()", 100);
        else if(document.getElementById("__ie_onload"))
                return true;

        if(typeof this.DOMContentLoadedCustom === "function")
        {
            if(this.DOMContentLoadedCustom())
                this.run();
            else
                setTimeout(this.name + ".schedule()", 250);

        }
        return true;
    },

    init: function()
    {
        if(document.addEventListener)
            document.addEventListener("DOMContentLoaded", function() { doOnLoad.run(); }, false);

        setTimeout("doOnLoad.schedule()", 100);

        function run()
        {
                doOnLoad.run();
        }

        if(typeof addEvent !== "undefined")
                addEvent(window, "load", run);
        else if(document.addEventListener)
                document.addEventListener("load", run, false);
        else if(typeof window.onload === "function")
        {
                var oldonload = window.onload;
                window.onload = function()
                {
                        doOnLoad.run();
                        oldonload();
                };
        }
        else
            window.onload = run;

        // for IE
        /*@cc_on
                @if (@_win32 || @_win64)
                document.write("<script id=__ie_onload defer src=\"//:\"><\/script>");
                var script = document.getElementById("__ie_onload");
                script.onreadystatechange = function()
                {
                        if (this.readyState == "complete")
                        {
                                doOnLoad.run(); // call the onload handler
                        }
                };
                @end
        @*/
    }
};

var todo = function()
{
	var instanceOne = new RoloFlo();
	instanceOne.init({ RoloFloID:'roloflo' });
};
doOnLoad.init();
doOnLoad.add(todo);