    function Slideshow(slideshowArea, query, showText, entityType, html, maxImageWidth, maxImageHeight, smallMode) {
        this.slideshowArea = slideshowArea;
        this.query = query;
        this.showText = showText; 
        this.smallMode = smallMode;
        this.index = 0;
        this.pageSize = 10;
        this.startIndex = 0;
        this.resultCount = 0;
        this.entityType = entityType;
        this.results = null;
        this.maxImageWidth = (maxImageWidth) ? maxImageWidth : 250;
        this.maxImageHeight = (maxImageHeight) ? maxImageHeight : 210;
        this.queryKey = '';
        this.VC_BASE = '';

        // integration hook
        if (window.slideshowStarted)
            window.slideshowStarted(this);

        if (!html)
            html = this.getMediaSlideshowHtml();
        this.slideshowArea.innerHTML = html;

        if (this.showsCaption()) {
            // create popup area
            this.moreInfoArea = document.createElement("DIV");
            this.moreInfoArea.style.position="absolute";
            this.moreInfoArea.style.zIndex="1000";
            this.moreInfoArea.style.display = "none";
            this.moreInfoArea.style.width="250px" ;
            this.moreInfoArea.style.color="#487802";
            this.moreInfoArea.className = "captionPopup";
            
            //var sibling = this.slideshowArea.parentNode;
            var sibling = document.body.firstChild;
            sibling.parentNode.insertBefore(this.moreInfoArea, sibling);
        }

        findElementById("moveNextButton", this.slideshowArea).onmousedown = delegateCallback(this, this.moveNext);
        findElementById("movePreviousButton", this.slideshowArea).onmousedown = delegateCallback(this, this.movePrevious);
        this.getData();
    }

    Slideshow.prototype.getData = function() {
        findElementById("titleAnchor", this.slideshowArea).innerHTML = "Loading...";
        findElementById("imageArea", this.slideshowArea).style.display = "none";
        if (this.showText)
            findElementById("textArea", this.slideshowArea).innerHTML = '';

        var url = "/PortalService?event=getData";
        url += "&" + this.query;
        url += "&query=" + encode(this.queryKey);
        url += "&mode=goodData";
        url += "&start=" + this.startIndex + "&end=" + (this.startIndex+this.pageSize);
        sendRequest(url, null, delegateCallback(this, this.processData));
    }

    Slideshow.prototype.getMediaSlideshowHtml = function() {
        var iconStyle = "-LG";
        var html = "";
        html += '<table cellspacing="0" cellpadding="0"><tr>';
        html += '<td style="padding:3px" style="-moz-user-select:none" onselectionstart="return false"><nobr>';
        html += '<a href="#" onclick="return false" id="movePreviousButton"><img height="18" src="' + this.VC_BASE + '/ui/media/arrow-left-small' + iconStyle + '.png" alt="Previous" border="0"/></a>&nbsp;';
        html += '<a href="#" onclick="return false" id="moveNextButton"><img height="18" src="' + this.VC_BASE + '/ui/media/arrow-right-small' + iconStyle + '.png" alt="Next" border="0"/></a>';
        html += '</nobr></td>';
        html += '<td width="250" height="26">&nbsp;<a id="titleAnchor" target="_top" style="font-weight:bold">Loading...</a></td>';
        if (this.showText)
            html += '</tr><tr><td style="padding:5px" colspan="2" id="textArea"></td>'
        html += '</tr><tr><td colspan="2" align="center"><div id="imageArea"></div></td></tr> </table>';
        return html;
    }

    Slideshow.prototype.processData = function(xhr) {
        var dom = xhr.documentElement;
        this.queryKey = decode(dom.getElementsByTagName("query-key")[0].firstChild.data);
        this.resultCount = dom.getElementsByTagName("result-count")[0].firstChild.data;

        if (this.resultCount == 0) {
            this.slideshowArea.innerHTML = "<div style='padding-top:10px'><img src='/ui/media/media-photo-n.png'></div>";
            if (window.slideshowEmpty)
                window.slideshowEmpty(this);

        } else {
            this.results = dom.getElementsByTagName("item");
            this.renderData();
        }
    }

    Slideshow.prototype.renderData = function() {
        if (this.resultCount == 0)
            return;

        var vState = (this.index >= this.resultCount-1) ? "hidden" : "visible";
        findElementById("moveNextButton", this.slideshowArea).style.visibility = vState;
        vState = (this.index == 0) ? "hidden" : "visible";
        findElementById("movePreviousButton", this.slideshowArea).style.visibility = vState;

        var result = this.results[this.index - this.startIndex];

        // integration hook
        if (window.slideshowFrameRendering)
            window.slideshowFrameRendering(this, result);

        var name = decode(result.childNodes[1].firstChild.data);
        name = name.replace(/Travel Guide/, '');
        var text = result.childNodes[2].firstChild;
        if (text)
            text = decode(text.data);
        var link = result.childNodes[0].firstChild;
        if (link)
            link = link.data;
        link = this.VC_BASE + link;

        var videoPath="", imageSrc="";
        var imageHeight = 0;
        var media = result.getElementsByTagName("media");
        if (media.length > 0) {
            media = media[0];
            if (this.smallMode)
                imageSrc = this.VC_BASE + media.getAttribute("path-small");
            else
                imageSrc = this.VC_BASE + media.getAttribute("path-medium");
            imageHeight = parseInt(media.getAttribute("height"));
            if (media.getAttribute("type") == "Video")
                videoPath = decode(media.getAttribute("path-video"));
        }
        var propsHtml = "";
        var props = result.getElementsByTagName("property");
        for (var k=0; k < props.length; k++) {
            var propName = props[k].getAttribute("name");
            var propLink = props[k].getAttribute("link");
            var propText = decode(props[k].firstChild.data);
            propsHtml += "<tr><td class='fieldLabel' width='80'>" + propName + ":</td><td><a href='" + propLink + "'>" + propText + "</a></td></tr>";
        }
        if (propsHtml) {
            propsHtml = "<table width='100%' cellpadding='0' cellspacing='0'><tr><td bgcolor='#cee1a9' height='1'></td></tr></table><div style='width:100%; background-color:#ffffbf'><table cellpadding='0' cellspacing='5'>" + propsHtml + "</table></div>";
        }

        this.render(name, text, link, imageSrc, imageHeight, videoPath, propsHtml);
    }

    Slideshow.prototype.hideCaption = function() {
        if (!this.overPopup) {
            this.moreInfoArea.style.display = "none";
            var imageArea = findElementById("imageArea", this.slideshowArea);
            if (imageArea)
                imageArea.style.visibility = "";
        }
    }

    Slideshow.prototype.renderPopupCaption = function(imageArea, titleAnchor) {
        this.overPopup = false;
        this.moreInfoArea.onmouseover = delegateCallback(this, function() {
            this.overPopup = true;
        });
        this.moreInfoArea.onmouseout = delegateCallback(this, function() {
            this.overPopup = false;
            if (window.delegateCallback)  // for unload
                setTimeout(delegateCallback(this, this.hideCaption), 500);
        });
        titleAnchor.onmouseover = delegateCallback(this, function() {
            this.moreInfoArea.style.display = "";
            if (this.entityType != 2 || imageArea.style.display == 'none') {
                this.moreInfoArea.style.top = findPosY(titleAnchor) + 25 + "px";
                this.moreInfoArea.style.left = findPosX(titleAnchor) + "px";
            } else {
                this.moreInfoArea.style.top = findPosY(imageArea) + "px";
                this.moreInfoArea.style.left = (findPosX(imageArea)) + "px";
                imageArea.style.visibility = "hidden";
            }
        });
        titleAnchor.onmouseout = delegateCallback(this, function() {
            setTimeout(delegateCallback(this, this.hideCaption), 500);
        });
    }

    Slideshow.prototype.showsCaption = function() {
        return (this.entityType != 6);
    }

    Slideshow.prototype.render = function(name, text, link, imageSrc, imageHeight, videoPath, props) {
        var titleAnchor = findElementById("titleAnchor", this.slideshowArea);
        var imageArea = findElementById("imageArea", this.slideshowArea);
        if (this.showsCaption())
            this.moreInfoArea.innerHTML = "<div style='padding:5px'>" + name + "</div>" + props;  
        name = this.wrap(name, 23); // was 22
        titleAnchor.innerHTML = name;
        titleAnchor.href = link;

        if (this.showsCaption())
            this.renderPopupCaption(imageArea, titleAnchor);

        var maxTextSize = (this.smallMode) ? 100 : 400;

        var html = '';
        if (videoPath) {
            html = videoPath;
            if (videoPath.indexOf("videoegg.com") >= 0) {
                if (window.VE_getPlayerAPI) { // if it can be loaded
                    var VE_api = VE_getPlayerAPI('1.2');
                    html = VE_api.getPlayerHTML(videoPath, this.maxImageWidth, this.maxImageHeight, false, '/ui/media/video-logo.png', '', false,'','');
                } else {
                    html = '';
                }
            } else if (videoPath.indexOf("<") < 0) {
                html = '<embed src="' + videoPath + '" width="' + this.maxImageWidth + '" height="' + this.maxImageHeight + '"></embed>';
            } else {
                html = html.replace(/width=['"]?\d*['"]?/g, 'width="250"');
                html = html.replace(/height=['"]?\d*['"]?/g, 'height="210"');
            }

            imageArea.innerHTML = html;
            imageArea.style.display = "";
        } else if (imageSrc) {
            imageHeight = imageHeight * this.maxImageWidth / 250;
            var h;
            if (imageHeight < this.maxImageHeight)
                h = imageHeight;  // use real height
            else
                h = this.maxImageHeight;  // limit to max
            var w = 250 * this.maxImageHeight / imageHeight;
            if (w > this.maxImageWidth)
                w = this.maxImageWidth;

            html = '<a target="_top" href="' + link + '"><img border="0" src="' + imageSrc + '" height="' + h + '" width="' + w + '"></a>';
            imageArea.style.display = "";
        } else {
            imageArea.style.display = "none";
            if (this.smallMode)
                maxTextSize = 200;
        }
        imageArea.innerHTML = html;

        if (this.showText) {
            text = this.wrap(text, maxTextSize);
            findElementById("textArea", this.slideshowArea).innerHTML = text;
        }

        // integration hook
        if (window.slideshowFrameRendered)
            window.slideshowFrameRendered(this);

    }

    Slideshow.prototype.moveNext = function(evt) {
        this.index++;
        if (this.index >= this.resultCount)
            this.index = this.resultCount - 1;

        // integration callback
        if (window.slideshowMovedNext)
            window.slideshowMovedNext(this);

        if (this.index >= this.startIndex + this.pageSize) {
            this.startIndex += this.pageSize;
            this.getData();
        } else
            this.renderData();
    }
    Slideshow.prototype.movePrevious = function(evt) {
        this.index--;
        if (this.index < 0)
            this.index = 0;

        // integration callback
        if (window.slideshowMovedPrevious)
            window.slideshowMovedPrevious(this);

        if (this.index < this.startIndex) {
            this.startIndex -= this.pageSize;
            this.getData();
        } else
            this.renderData();
    }

    Slideshow.prototype.selectSlide = function(pos) {
        // integration callback
        if (window.slideshowFrameSelected)
            window.slideshowFrameSelected(this);

        this.index = this.startIndex + pos;
        this.renderData();
    }

    Slideshow.prototype.wrap = function(value, size) {
        if (!value)
            return "";

        if (value.length > size) {
            size = value.lastIndexOf(" ", size);
            value = value.substring(0, size) + "...";
        }
        return value;
    }

