var leafBox = function(){}
leafBox.prototype.isOpen = false;
leafBox.prototype.isLeafBox = true;
leafBox.prototype.backgroundOpacity = 8;

// define class vars
leafBox.keyword = 'leafBox';
leafBox.attribute = 'rel';
leafBox.defaultStyleName = 'default';

leafBox.elementClassPrefix = 'leafBox';

leafBox.containerClassName = 'leafBoxContainer';
leafBox.containerIdPrefix = leafBox.containerClassName.concat( '_' );

leafBox.stylePath = '/styles/leafBox/'; // path to main leafBox.css file
leafBox.baseStyleFile = 'leafBox.css';

leafBox.scriptPath = '/js/leafBox/';

leafBox.paramsProperty = 'leafBoxParams';

leafBox.ie6WindowedElements = ['select', 'object'];

leafBox.attributePattern = null;
leafBox.handlerProperties = {};

leafBox.existingTypes = {};
leafBox.usedStyles = {};
leafBox.instances = {};
leafBox.scripts = {};
leafBox.styleSheets = {};
leafBox.links = [];


// define class functions
leafBox.init = function()
{
    // check if needed functions are supported
    if (!leafBox.canRun())
    {
        return null;
    }


    this.loadBaseStyleSheet();

    var body = document.getElementsByTagName('body')[0];
    this.attachToLinks( body );

    this.setupWindowHandlers();

}

leafBox.canRun = function()
{
    // check if needeed functionality is available
    var pageSize = this.getPageSize();
    if (!pageSize)
    {
        return false;
    }
    return true;
}

leafBox.setupWindowHandlers = function()
{
    this.attachEventHandler( window, 'resize', this.windowResized);
    this.attachEventHandler( window, 'scroll', this.windowScrolled);
}

leafBox.windowScrolled = function()
{
    for ( instName in this.leafBox.instances )
    {
        this.leafBox.instances[instName].windowScrolled();
    }
    return true;
}

leafBox.windowResized = function()
{
    for ( instName in this.leafBox.instances )
    {
        this.leafBox.instances[instName].windowResized();
    }
    return true;
}


// scans given element for links and attaches click handlers to all leafbox links
leafBox.attachToLinks = function( container )
{
    var links = container.getElementsByTagName('a');
    if (!links)
    {
        return;
    }

    for (var i=0; i<links.length; i++)
    {
        this.processLink (links[i]);
    }


    return;
}

// returns regexp for detecting if a link is marked for leafbox
leafBox.getAttributePattern = function()
{
    if (!this.attributePattern)
    {
        this.attributePattern = new RegExp('^'.concat( this.keyword ));
    }

    return this.attributePattern;
}

// returns the name of the property in which to store the handler for a given event
leafBox.getHandlerProperty = function( eventName )
{
    if (!this.handlerProperties[eventName])
    {
        this.handlerProperties[eventName] = this.keyword.concat(eventName, 'Handler');
    }

    return this.handlerProperties[eventName];
}

// checks if the given link is marked for leafbox
// and attempts to attach the click handler
leafBox.processLink = function( link )
{
    if ((!link) || (!link.tagName) || (link.tagName.toLowerCase() != 'a'))
    {
        return false;
    }

    var attr = link.getAttribute(this.attribute);
    if (!attr)
    {
        return false;
    }

    var pattern = this.getAttributePattern();
    if (!attr.match(pattern))
    {
        return false;
    }

    // load link leafBox params
    this.loadLinkParams( link );
    this.addLink( link );

    return this.attachEventHandler( link, 'click', this.linkClicked );
}

leafBox.addLink = function( link )
{
    if (link.addedToLeafBox)
    {
        return;
    }
    link.addedToLeafBox = true;
    leafBox.links[leafBox.links.length] = link;
}


// generic function for attaching event handlers
leafBox.attachEventHandler = function( obj, eventName, fn )
{
    var prop = this.getHandlerProperty( eventName );
    obj[prop] = fn;
    var eventProp = 'on'.concat(eventName);
    var oldHandler = 'old'.concat(eventProp);
    obj[oldHandler] = obj[eventProp];
    obj[eventProp] = function()
    {
        if (this[oldHandler])
        {
            var result = this[oldHandler]();
            if (!result)
            {
                return result;
            }
        }
        return this[prop]();
    }

    return true;
}

leafBox.ucFirst = function (str)
{
   return str.substr(0,1).toUpperCase() + str.substr(1, str.length);
}
leafBox.lcFirst = function (str)
{
   return str.substr(0,1).toLowerCase() + str.substr(1, str.length);
}

// the function that gets called when a leafbox link is clicked
leafBox.linkClicked = function()
{
    // 'this' refers to the link element

    var params = leafBox.getLinkParams( this );

    if (!params)
    {
        // could not load params, abort, return true (proceed with the click, let the link open)
        return true;
    }

    var leafBoxOk = leafBox.show( params );

    return !leafBoxOk;
}

// extracts leafbox params from the given link
leafBox.getLinkParams = function (link)
{

    if (!link[this.paramsProperty])
    {

        if (!leafBox.loadLinkParams( link ))
        {
            return null;
        }
    }

    // get main leafbox params from attribute
    var params = link[this.paramsProperty];

    //  build leafbox content url
    var url = link.href;
	var delimiter = (url.indexOf('?') == -1) ? '?' : '&';
    url = url.concat(delimiter, this.keyword, '=', params.style, '&random=',  Math.random());
    params.url = url;

    return params;
}

// read string from rel="" and parse into an object, store in params property of the link
leafBox.loadLinkParams = function ( link )
{
    var href = link.href;
    if (!href)
    {
        return false;
    }

    var params = null;
    var attrVal = link.getAttribute(this.attribute);
    if (attrVal)
    {
         params = this.parseQuery(attrVal);
    }

    if (!params)
    {
        return false;
    }

    // if specific style not given, use default
    if (!params.style)
    {
        params.style = this.defaultStyleName;
    }
    params.href = href;


    // get type ( validate given type or attempt to detect from href if not explicitly given)
    // abort on failure
    params.type = this.getType( params );

    if (!params.type)
    {
        return false;
    }

    // add title from link, if set
    if (link.title)
    {
        params.title = link.title;
    }

    params.link = link;

    this.loadStyleJs( params.style);
    this.loadStyleCss( params.style );

    // this.usedTypes[params.type] = true;
    this.usedStyles[params.style] = true;

    link[this.paramsProperty] = params;
    return true;
}

leafBox.getType = function ( params )
{
    var type = params.type;
    if (params.gallery)
    {
        type = 'gallery';
    }
    else if (!type)
    {
        var imagePattern = /(\.jpg|\.jpeg|\.png|\.gif)$/gi;
	    var imageExtension = params.href.match(imagePattern);
        if (imageExtension)
        {
            type = 'image';
        }
        else
        {
            type = 'page'
        }
    }
    if (!this.typeExists(type))
    {
        return null;
    }
    return type;
}

leafBox.typeExists = function(typeName)
{
    //
    if (this.existingTypes[typeName])
    {
        return true;
    }

    var typeClass = 'leafBox_'.concat(typeName);
    if (this.isLeafBoxClass(typeClass))
    {
        this.existingTypes[typeName] = true;
        return true;
    }

    return false;
}



leafBox.parseQuery = function(query)
{
   var params = {};
   if (!query)
   {
       return params;
   }
   var pairs = query.split(/[;&]/);
   for ( var i = 0; i < pairs.length; i++ )
   {
      var keyValue = pairs[i].split('=');
      if ( !keyValue || keyValue.length != 2 )
      {
          continue;
      }
      var key = unescape( keyValue[0] );
      var val = unescape( keyValue[1] );
      val = val.replace(/\+/g, ' ');
      params[key] = val;
   }

   return params;
}

leafBox.show = function ( params )
{
    // get reference to leafbox of the given style & type
    var instance = this.getInstance( params );
    if (!instance)
    {

        return false;
    }

    return instance.open( params );
}

leafBox.closeAllInstances = function()
{
    for ( instName in this.instances )
    {
        this.instances[instName].close();
    }
}

leafBox.getInstance = function ( params )
{
    if ((!params.style) || (!params.type))
    {
        return null;
    }

    var instanceName = this.getInstanceName( params.type, params.style);

    if (!this.instances[instanceName])
    {
        var className = 'leafBox_'.concat(instanceName);
        if (!this.isLeafBoxClass(className))
        {

            return null; // class not loaded
        }

        var instance = new window[className];
        if (!instance.loadContainer(params))
        {
            return null;
        }
        this.instances[instanceName] = instance;
    }

    return this.instances[instanceName];
}

leafBox.getInstanceName = function( type, style)
{
    return type.concat('_', style );
}

leafBox.getContainerId = function( type, style )
{
    var instanceName = this.getInstanceName( type, style);
    return this.containerIdPrefix.concat( instanceName );
}

leafBox.loadBaseStyleSheet = function ()
{
    var fileName = this.stylePath.concat( this.baseStyleFile )
    return leafBox.loadCss ( fileName );
}

leafBox.loadStyleCss = function( styleName )
{
    var fileName = this.stylePath.concat( styleName, '.css');
    return this.loadCss ( fileName );
}

leafBox.loadStyleJs = function( styleName )
{
    var fileName = this.scriptPath.concat(styleName, '.js');
    return this.loadJs( fileName );
}

leafBox.loadCss = function( fileName )
{
    if (!this.styleSheets[fileName])
    {
        var attrs = {
            'rel' : 'stylesheet',
            'type' : 'text/css',
            'href' : fileName
        };
        this.styleSheets[fileName] = this.loadFile('link', attrs );
    }
    return this.styleSheets[fileName];
}

leafBox.loadJs = function ( fileName )
{

    if (!this.scripts[fileName])
    {
        var attrs = {
            'type' : 'text/javascript',
            'src' : fileName
        };
        this.scripts[fileName] = this.loadFile('script', attrs );
    }
    return this.scripts[fileName];
}

leafBox.loadFile = function(tag, attrs)
{
    var el = document.createElement(tag);
    for (attrName in attrs)
    {
        el.setAttribute( attrName, attrs[attrName]);
    }

    return document.getElementsByTagName('head')[0].appendChild(el);
}

leafBox.isLeafBoxClass = function(  className )
{
    if (
        (typeof window[className] != 'function')
        ||
        (!window[className].prototype.isLeafBox)
    )
    {
        return false;
    }
    return true;
}

leafBox.getPageSize = function()
{
	var xScroll, yScroll;
    var scrollBarWidth = leafBox.getScrollbarWidth();

	if (window.innerHeight && window.scrollMaxY)
	{
		xScroll = window.innerWidth + window.scrollMaxX - scrollBarWidth;
		yScroll = window.innerHeight + window.scrollMaxY;//  - scrollBarWidth;
	}
	else if (document.body.scrollHeight > document.body.offsetHeight)
	{ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	}
	else
	{ // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}

	var windowWidth, windowHeight;

	if (self.innerHeight)
	{	// all except Explorer
		if(document.documentElement.clientWidth)
		{
			windowWidth = document.documentElement.clientWidth;
		}
		else
		{
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight)
	{ // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	}
	else if (document.body)
	{ // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}

	// for small pages with total height less then height of the viewport
	if (yScroll < windowHeight)
	{
		pageHeight = windowHeight;
	}
	else
	{
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if (xScroll < windowWidth)
	{
		pageWidth = windowWidth;
	}
	else
	{
		// pageWidth = windowWidth;
		pageWidth = xScroll;
	}

	// scroll offsets
	var docElem = document.documentElement;
	var scrollX = self.pageXOffset || (docElem&&docElem.scrollLeft) || document.body.scrollLeft;
	var scrollY = self.pageYOffset || (docElem&&docElem.scrollTop) || document.body.scrollTop;

	var pageSize = {
	    'pageWidth' : pageWidth,
	    'pageHeight' : pageHeight,
	    'viewportWidth' : windowWidth,
	    'viewportHeight' : windowHeight,
	    'scrollX' : scrollX,
	    'scrollY' : scrollY
	}
	return pageSize;

}

leafBox.getScrollbarWidth = function()
{
    // look for cached version
    if (typeof window.scrollbarWidth == 'number')
    {
        return window.scrollbarWidth;
    }

    // create test container and inner overflow box
    var outerBox = document.createElement('div');
    outerBox.style.position = 'absolute';
    outerBox.style.top      = '100px';
    outerBox.style.left     = '100px';
    outerBox.style.width    = '200px';
    outerBox.style.height   = '200px';
    outerBox.style.overflow = 'hidden';

    var innerBox = document.createElement('div');
    innerBox.style.width    = '100%';
    innerBox.style.height   = '400px'; // cause overflow

    outerBox.appendChild(innerBox);
    document.body.appendChild(outerBox);

    // measure inner box size with overflow hidden
    var sizeWithNoScrollbar = innerBox.offsetWidth;

    // measure width with overflow scroll
    outerBox.style.overflow = 'auto';
    var sizeWithScrollbar = innerBox.offsetWidth;
    outerBox.parentNode.removeChild(outerBox);

    window.scrollbarWidth = sizeWithNoScrollbar - sizeWithScrollbar;

    return window.scrollbarWidth;
}


// instance functions
leafBox.prototype.loadContainer = function( params )
{
    // loads corresponding html for given style and type

    var html = this.getContainerHtml( params.type, params.style);

    if (!html)
    {
        return false;
    }

    var container = document.createElement('div');
    var containerId = leafBox.getContainerId( params.type, params.style);
    container.className = leafBox.containerClassName.concat(' leafBox_', params.style);
    container.setAttribute('id', containerId);

    container.innerHTML = html;

    this.container = container;
    document.body.appendChild(this.container);

    this.loadElements();

    return true;
}

leafBox.prototype.getContainerHtml = function( type, style)
{
    var pageUrl = window.location.href.split('#')[0];
    var delimiter = (pageUrl.indexOf('?') == -1) ? '?' : '&';
    var leafBoxUrl = pageUrl.concat(delimiter, 'getLeafBox=', type, '&', 'leafBoxStyle=', style);

    var html = openXmlHttpGet( leafBoxUrl, true);
    return html;
}

leafBox.prototype.loadElements = function()
{

    var prefix = leafBox.elementClassPrefix;
    var prefixLen = prefix.length;

    this.elements = {};
    var elements = this.container.getElementsByTagName('*');
    for (var i = 0; i < elements.length; i++)
    {
        var el = elements[i];
        if (!el.className)
        {
            continue;
        }
        var classNames = el.className.split(' ');
        for (var j=0; j<classNames.length; j++)
        {
            var className = classNames[j];
            if (
                (!className)
                ||
                (className.length <= prefixLen)
                ||
                (className.substr(0, prefixLen) != prefix)
            )
            {
                continue;
            }

            var propertyName = leafBox.lcFirst( className.substr( prefixLen, className.length - prefixLen) );
            this.elements[propertyName] = el;

        }
    }
}

// main function for showing leafbox content
leafBox.prototype.open = function ( params )
{
     // all function calls here will get params as argument

    if (!this.isOpen)
    {
        // show background
        this.showContainer(params);
        this.showBackground(params);
    }

    if (this.isOpen)
    {
        // hide content wrapper
        this.unloadContent(params);
    }


    // show progress bar
    this.showLoader( params );

    // load content (stilll hidden)
    this.loadContent( params );  // sequential loading

    // this.enableKeyboard( params );

    this.isOpen = true;
    return true;
}


leafBox.prototype.enableKeyboard = function(params)
{
    var instance = this;
    document.onkeydown = function( e )
    {
        instance.keyPressed( e, params );
    }
}

leafBox.prototype.disableKeyboard = function(params)
{
    document.onkeydown = null;
}

leafBox.prototype.keyPressed = function(e, params)
{
	if (e == null) { // ie
		keycode = event.keyCode;
		escapeKey = 27;
	} else { // mozilla
		keycode = e.keyCode;
		escapeKey = e.DOM_VK_ESCAPE;
	}
}

leafBox.prototype.close = function(params)
{
    this.hideContainer(params);
    this.hideLoader(params);

    // this.disableKeyboard();
    this.unloadContent();
    this.hideBackground(params);

    this.isOpen = false;
}

leafBox.resizeToPage = function( el )
{
    if (!el)
    {
        return false;
    }

    el.style.display = 'none';

    var pageSize = this.getPageSize();

    el.style.width = pageSize.pageWidth + 'px';
    el.style.height = pageSize.pageHeight + 'px';
    el.style.display = 'block';

    return true;
}

leafBox.centerBox = function( el, triggerEventName )
{
    if (!el)
    {
        return false;
    }

    var page = this.getPageSize();

	var width = el.offsetWidth ||  el.style.pixelWidth;
	var height = el.offsetHeight || el.style.pixelHeight;

	if (
	   (typeof width == 'undefined')
	   ||
	   (typeof height == 'undefined')
    )
	{
        return false;
	}

	var moveX = true, moveY = true;


	var top = Math.round(page.viewportHeight / 2) - Math.round(height / 2);
	var left = Math.round(page.viewportWidth / 2) - Math.round(width / 2);

    if (isNaN(top) || isNaN(left))
    {
        return false;
    }

    if (top < 0)
    {
        top = 0;
    }


    if ((height > page.viewportHeight ) && (triggerEventName == 'scroll'))
    {
        // image does not fit in window vertically, user scrolled.
        // do not reposition box vertically
        moveY = false;

    }
    else
    {
        top += page.scrollY;
    }
    if (left < 0)
    {
        left = 0;
    }
    if ((width > page.viewportWidth)  && (triggerEventName == 'scroll'))
    {
        // image does not fit in window horizontally, user scrolled.
        // do not reposition box horizontally
        moveX = false;
    }
    else
    {
        left += page.scrollX;
    }

    if (moveY)
    {
    	el.style.top = top + 'px';
    }

    if (moveX)
    {
	    el.style.left = left + 'px';
    }

	return true;
}

leafBox.isIE6OrOlder = function()
{
    return false /*@cc_on || @_jscript_version < 5.7 @*/;
}

leafBox.getWindowedTagNames = function()
{
    if (!this.isIE6OrOlder())
    {
        return [];
    }
    return this.ie6WindowedElements;
}

leafBox.hideWindowedControls = function()
{
    var windowedTagNames = this.getWindowedTagNames();

    for (var i=0; i<windowedTagNames.length; i++)
    {
        var elements = document.getElementsByTagName( this.ie6WindowedElements[i] );
        for (var j=0; j<elements.length; j++)
        {
            var el = elements[j];
            var curVisibility = el.currentStyle.visibility;
            el.leafBoxVisibility = curVisibility;
            el.style.visibility = 'hidden';
        }
    }

}

leafBox.restoreWindowedControls = function()
{
    var windowedTagNames = this.getWindowedTagNames();
    for (var i=0; i<windowedTagNames.length; i++)
    {
        var elements = document.getElementsByTagName( this.ie6WindowedElements[i] );
        for (var j=0; j<elements.length; j++)
        {
            var el = elements[j];
            if (el['leafBoxVisibility'])
            {
                el.style.visibility = el.leafBoxVisibility;
            }
        }
    }

}

// functions for the types to override
leafBox.prototype.windowResized = function()
{
    this.windowResizedOrScrolled('resize');
}
leafBox.prototype.windowScrolled = function()
{
    this.windowResizedOrScrolled('scroll');
}

leafBox.prototype.windowResizedOrScrolled = function(triggerEventName)
{
    if (!this.isOpen)
    {
        return;
    }
    leafBox.resizeToPage( this.elements.background );
    leafBox.centerBox ( this.elements.progress, triggerEventName );
    leafBox.centerBox ( this.elements.contentWrap, triggerEventName );
}




leafBox.prototype.showContainer = function(params)
{
    this.container.style.display = 'block';
}
leafBox.prototype.hideContainer = function(params)
{
    this.container.style.display = 'none';
}
leafBox.prototype.showBackground = function(params)
{
    if (!this.elements.background)
    {
        return false;
    }
    leafBox.hideWindowedControls();
    leafBox.resizeToPage( this.elements.background );
    this.elements.background.style.display = 'block';

    var instance = this;
    this.elements.background.onclick = function()
    {
        instance.close(params);
    }
    return true;

}

leafBox.prototype.hideBackground = function(params)
{
    if (!this.elements.background)
    {
        return false;
    }
    this.elements.background.style.display = 'none';
    leafBox.restoreWindowedControls();
    return true;
}

leafBox.prototype.showLoader = function(params)
{
    if (!this.elements.progress)
    {
        return false;
    }

    var loader = this.elements.progress;

    // show as hidden
    loader.style.visibility = 'hidden';
    loader.style.display = 'block';

    // center
    leafBox.centerBox( loader, 'showLoader' );

    loader.style.visibility = 'visible';
    return true;
}
leafBox.prototype.hideLoader = function(params)
{
    if (!this.elements.progress)
    {
        return false;
    }

    var loader = this.elements.progress;

    // park in corner
    var s = loader.style;
    s.visibility = 'hidden';
    s.left = '0px';
    s.top = '0px';
    s.display = 'none';

    return true;
}
leafBox.prototype.showContent    = function(params)
{
    if (this.elements['content'])
    {
        this.elements.content.style.visibility = 'visible';
    }
    if (this.elements['contentWrap'])
    {
        this.elements.contentWrap.style.visibility = 'visible';
    }
    return true;
}


leafBox.prototype.loadContent    = function(params) { return true; }
leafBox.prototype.unloadContent  = function(params) { return true; }


leafBox.prototype.resizeContent = function(width, height)
{
    this.elements.content.style.width = width + 'px';
    this.elements.content.style.height = height + 'px';

    leafBox.centerBox( this.elements.contentWrap, 'resizeContent' );
    return true;
}

var leafBoxOldOnload = window.onload;
window.onload = function()
{
    if (typeof leafBoxOldOnload == 'function')
    {
         leafBoxOldOnload();
    }

    leafBox.init();
}

///////////////////////
/////////////////////// IMAGE CLASS
///////////////////////

var leafBox_image = function(){}
leafBox_image.prototype = new leafBox;

leafBox_image.prototype.loadContent = function(params)
{
    // show hidden
    var instance = this;
    var el = this.elements;

    if (!this.isOpen)
    {
        el.contentWrap.style.visibility = 'hidden';
        el.contentWrap.style.display = 'block';
    }

    el.content.style.visibility = 'hidden';
    el.content.style.display = 'block';

    // load image
    var imageSrc = params.href;

    this.removeImage();

    el.image = document.createElement('img');
    el.image.onload = function()
    {
        instance.resizeContent( this.width, this.height );
        el.content.appendChild( this );
        instance.hideLoader();
        instance.showContent(params);
        this.onload = null;
    }
    el.image.src = imageSrc;



    // set title
    this.setTitle(params);

    el.image.onclick = function()
    {
        instance.close();
    }

    if (el.close)
    {
        el.close.onclick = function()
        {
            instance.close();
            return false;
        }
    }

    return true;

}

leafBox_image.prototype.unloadContent = function(params)
{
    this.removeImage();
}

leafBox_image.prototype.removeImage = function()
{
    if ((this.elements['image']) && (this.elements.image.parentNode))
    {
        this.elements.image.parentNode.removeChild( this.elements.image );
        this.elements.image = null;
    }
    return null;
}

leafBox_image.prototype.setTitle = function(params)
{
    if (!this.elements.title)
    {
        return false;
    }
    this.elements.title.innerHTML = '';

    if (typeof params.title != 'undefined')
    {
        var titleNode = document.createTextNode(params.title);
        this.elements.title.appendChild(titleNode);
    }
    return true;
}


///////////////////////
/////////////////////// GALLERY CLASS
///////////////////////

var leafBox_gallery = function(){}
leafBox_gallery.prototype = new leafBox;
leafBox_gallery.prototype.imageLoadContent = leafBox_image.prototype.loadContent;
leafBox_gallery.prototype.removeImage = leafBox_image.prototype.removeImage;
leafBox_gallery.prototype.setTitle = leafBox_image.prototype.setTitle;

leafBox_gallery.prototype.loadContent = function(params)
{
    var loadImage = this.imageLoadContent(params);
    this.updateImageNavigation(params);
    return loadImage;
}

leafBox_gallery.prototype.updateImageNavigation = function(params)
{
    if (!this.areGalleriesLoaded())
    {
        this.loadGalleries();
    }

    var imageNumber = this.getGalleryLinkNumber( params.link, params.gallery );
    var imagesTotal = this.getGalleryLinkCount( params.gallery );

    this.updateGalleryPosition(params, imageNumber, imagesTotal);

    this.updateGalleryNavigationLinks(params, imageNumber, imagesTotal);

    this.elements.image.onclick = null; // remove onclick close from main image
}

leafBox_gallery.prototype.updateGalleryPosition = function(params, imageNumber, imagesTotal)
{
    if ((!this.elements['imageNumber']) || (!this.elements['imagesTotal']))
    {
        return false;
    }
    this.elements.imageNumber.innerHTML = imageNumber;
    this.elements.imagesTotal.innerHTML = imagesTotal;
    return true;
}

leafBox_gallery.prototype.updateGalleryNavigationLinks = function(params, imageNumber, imagesTotal)
{
    // var previousLinkExists = (imageNumber > 1);
    // var nextLinkExists = (imageNumber < imagesTotal);

    // locate navigation links
    var navLinks = this.elements.navigation.getElementsByTagName('a');
    var navPrevLink = navLinks[0];
    var navNextLink = navLinks[1];

    // get links from gallery list
    var galleryNextLink = this.galleries[params.gallery].links[imageNumber];
    var galleryPrevLink = this.galleries[params.gallery].links[imageNumber - 2];

    // for some reasone href copying doesnt work as expected in opera (9)
    // if hrefs are copied after cloning the navigation box
    // therefore temporarily set hrefs in main navigation
    navPrevLink.originalHref = navPrevLink.href;
    navNextLink.originalHref = navNextLink.href;
    if (galleryNextLink)
    {
        navNextLink.href = galleryNextLink.href;
    }
    if (galleryPrevLink)
    {
        navPrevLink.href = galleryPrevLink.href;
    }
    var newNav = this.elements.navigation.cloneNode(true);
    // set hrefs back to original values
    navPrevLink.href = navPrevLink.originalHref;
    navNextLink.href = navNextLink.originalHref;

    var newNavLinks = newNav.getElementsByTagName('a');
    var newNavPrevLink = newNavLinks[0];
    var newNavNextLink = newNavLinks[1];

    this.setupNavigationLink( newNavPrevLink, galleryPrevLink );
    this.setupNavigationLink( newNavNextLink, galleryNextLink );

    this.elements.content.appendChild(newNav);
    return true;
}

leafBox_gallery.prototype.setupNavigationLink = function( newLink, originalLink )
{
    var copyAttrs = ['rel', 'title'];
    var originalTitle = newLink.title;
    if (originalLink)
    {
        for (var i = 0; i< copyAttrs.length; i++)
        {
            newLink[copyAttrs[i]] = originalLink[copyAttrs[i]];
            newLink.href = originalLink.href;

        }
        newLink.originalLink = originalLink;
        leafBox.loadLinkParams( newLink );

        leafBox.attachEventHandler( newLink, 'click', leafBox.linkClicked );

        newLink.title = originalTitle;
    }
    else
    {
        newLink.parentNode.removeChild(newLink);
    }

    return null;
}

leafBox_gallery.prototype.unloadContent = function(params)
{
    this.removeImage();
    this.elements.content.innerHTML = '';
}

leafBox_gallery.prototype.areGalleriesLoaded = function()
{
    if (typeof this.galleries == 'undefined')
    {
        return false;
    }
    return true;
}

leafBox_gallery.prototype.loadGalleries = function()
{
    this.galleries = {};
    for (var i=0; i<leafBox.links.length; i++)
    {
        var link = leafBox.links[i];
        if (link[leafBox.paramsProperty].type != 'gallery')
        {
            continue;
        }
        var galleryName = this.getGalleryName( link[leafBox.paramsProperty].gallery );
        if (!this.galleries[galleryName])
        {
            this.galleries[galleryName] = {
                'links' : []
            };
        }

        this.galleries[galleryName].links[ this.galleries[galleryName].links.length ] = link;
    }

    return true;
}

leafBox_gallery.prototype.getGalleryName = function( galleryName )
{
    if (!galleryName)
    {
        galleryName = 'default';
    }
    return galleryName;
}

leafBox_gallery.prototype.galleryExists = function( galleryName )
{
    if (typeof this.galleries[galleryName] == 'undefined')
    {
        return false;
    }
    return true;
}

leafBox_gallery.prototype.getGalleryLinkNumber = function( link, galleryName )
{
    galleryName = this.getGalleryName( galleryName );
    if (!this.galleryExists( galleryName ))
    {
        return null;
    }

    for (var i=0; i<this.galleries[galleryName].links.length; i++)
    {
        if (
            (link.originalLink == this.galleries[galleryName].links[i])
            ||
            (link == this.galleries[galleryName].links[i])
        )
        {
            return i+1;
        }

    }
    return null;
}

leafBox_gallery.prototype.getGalleryLinkCount = function( galleryName )
{
    galleryName = this.getGalleryName( galleryName );
    if (!this.galleryExists( galleryName ))
    {
        return null;
    }
    return this.galleries[galleryName].links.length;
}


///////////////////////
/////////////////////// PAGE CLASS
///////////////////////


var leafBox_page = function(){}
leafBox_page.prototype = new leafBox;
leafBox_page.prototype.contentWidth = 400;  // some default width dimensions in case nothing is given
leafBox_page.prototype.contentHeight = 300;  // should be set explicitly via params

leafBox_page.prototype.loadContent = function(params)
{
    this.setSizeFromParams( params );

    // show hidden
    var instance = this;
    var el = this.elements;

    if (!this.isOpen)
    {
        el.contentWrap.style.visibility = 'hidden';
        el.contentWrap.style.display = 'block';
    }

    el.content.style.visibility = 'hidden';
    el.content.style.display = 'block';

    this.resizeContent(this.contentWidth, this.contentHeight );

    // var content = openXmlHttpGet( params.url, true);

    var callBack = function(xmlhttp, params)
    {
        if (!instance.isOpen)
        {
            // already closed, too late
            return;
        }
        el.content.innerHTML = xmlhttp.responseText;

        leafBox.attachToLinks( el.content );

        instance.hideLoader();
        instance.showContent(params);

        if (el.close)
        {
            el.close.onclick = function()
            {
                instance.close();
                return false;
            }
        }
    }
    loadXmlHttp(params.url, callBack, null, 'GET', null, true);
    return true;
}

leafBox_gallery.prototype.unloadContent = function(params)
{
    this.elements.content.innerHTML = '';
}


leafBox_page.prototype.setSizeFromParams = function( params )
{
    if (params['width'])
    {
        this.contentWidth = parseInt(params['width']);
    }

    if (params['height'])
    {
        this.contentHeight = parseInt(params['height']);
    }

}

