///////////////////////////////////////////////////////////////////////////////
//
//  Slideshow.js   			version 1.0
//
//  This file is provided by First Floor and implements parts of the Slideshow.
//
//  See also http://www.firstfloorsoftware.com/Slideshow.
// 
//  Copyright (c) 2007 First Floor. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
if (!window.Slideshow)
	window.Slideshow = {};


Slideshow.Scene = function() 
{
}

var STATE_RUNNING = 0;
var STATE_PAUSED = 1;
var STATE_STOPPED = 2;

var BUTTON_NONE = 0;
var BUTTON_PLAYPAUSE = 1;
var BUTTON_PREVNEXT = 2;
var BUTTON_PREVNEXTPAGE = 4;
var BUTTON_FULLSCREEN = 8;
var BUTTON_SAVE = 16;
var BUTTON_ALL = 31;

var MAX_SLIDES = 250000;

var SLPlugInControl = null;

Slideshow.Scene.prototype = {
    handleLoad: function(control, userContext, rootElement)
    {
        this.control = control;
        SLPlugInControl = control;

        this.control.content.onResize = Silverlight.createDelegate(this, this.onResized);
        this.control.content.onFullScreenChange = Silverlight.createDelegate(this, this.onFullResized);

        this.rootElement = rootElement;
        this.background = rootElement.findName("background");
        this.content = rootElement.findName("content");
        this.contentClip = rootElement.findName("contentClip");
        this.captionPane = rootElement.findName("captionPane");
        this.captionPaneAction = rootElement.findName("captionPaneAction");
        this.captionPaneRectangleAction = rootElement.findName("captionPaneRectangleAction");
        this.captionBackground = rootElement.findName("captionBackground");
        this.captionBackgroundColorTop = rootElement.findName("captionBackgroundColorTop");
        this.captionBackgroundColorBottom = rootElement.findName("captionBackgroundColorBottom");
        this.captionStoryboardShow = rootElement.findName("captionStoryboardShow");
        this.captionStoryboardHide = rootElement.findName("captionStoryboardHide");
        this.captionAnimation = rootElement.findName("captionAnimationShow");
        this.alwaysOnTopPane = rootElement.findName("alwaysOnTopPane");
        this.alwaysOnTopCaption = rootElement.findName("alwaysOnTopCaption");
        this.alwaysOnTopPaneShow = rootElement.findName("alwaysOnTopPaneShow");
        this.alwaysOnTopPaneHide = rootElement.findName("alwaysOnTopPaneHide");
        this.controlAnimation = rootElement.findName("controlAnimationShow");
        this.captionPaneClip = rootElement.findName("captionPaneClip");
        this.controlPaneClip = rootElement.findName("controlPaneClip");
        this.caption = rootElement.findName("caption");
        this.controlPane = rootElement.findName("controlPane");
        this.controlPaneShow = rootElement.findName("controlPaneShow");
        this.controlPaneHide = rootElement.findName("controlPaneHide");
        this.controlBackground = rootElement.findName("controlBackground");
        this.controlBackgroundColorTop = rootElement.findName("controlBackgroundColorTop");
        this.controlBackgroundColorBottom = rootElement.findName("controlBackgroundColorBottom");
        this.alwaysOnTopControlPane = rootElement.findName("alwaysOnTopControlPane");
        this.alwaysOnTopControlCaption = rootElement.findName("alwaysOnTopControlCaption");
        this.alwaysOnTopControlPaneShow = rootElement.findName("alwaysOnTopControlPaneShow");
        this.thumbnailsPane = rootElement.findName("thumbnailsPane");
        this.trackerPane = rootElement.findName("trackerPane");
        this.tracker = rootElement.findName("tracker");
        this.buttonPane = rootElement.findName("buttonPane");
        this.errorPane = rootElement.findName("errorPane");
        this.progressPane = rootElement.findName("progressPane");
        this.progress = rootElement.findName("progress");
        this.progressIn = rootElement.findName("progressIn");
        this.progressOut = rootElement.findName("progressOut");

        this.nextImagePane = rootElement.findName("nextImagePane");
        this.nextImageActionPane = rootElement.findName("nextImageActionPane");
        this.nextImageBackground = rootElement.findName("nextImageBackground");
        this.nextImageBackgroundTriangle = rootElement.findName("nextImageBackgroundTriangle");
        this.nextImageBackgroundTriangleOuterColor = rootElement.findName("nextImageBackgroundTriangleOuterColor");
        this.nextImageBackgroundTriangleInnerColor = rootElement.findName("nextImageBackgroundTriangleInnerColor");
        this.nextImageBackgroundOuterColor = rootElement.findName("nextImageBackgroundOuterColor");
        this.nextImageBackgroundInnerColor = rootElement.findName("nextImageBackgroundInnerColor");
        this.nextImageStoryboardShow = rootElement.findName("nextImageStoryboardShow");
        this.nextImageStoryboardHide = rootElement.findName("nextImageStoryboardHide");

        this.prevImagePane = rootElement.findName("prevImagePane");
        this.prevImageActionPane = rootElement.findName("prevImageActionPane");
        this.prevImageBackground = rootElement.findName("prevImageBackground");
        this.prevImageBackgroundTriangle = rootElement.findName("prevImageBackgroundTriangle");
        this.prevImageBackgroundTriangleOuterColor = rootElement.findName("prevImageBackgroundTriangleOuterColor");
        this.prevImageBackgroundTriangleInnerColor = rootElement.findName("prevImageBackgroundTriangleInnerColor");
        this.prevImageBackgroundOuterColor = rootElement.findName("prevImageBackgroundOuterColor");
        this.prevImageBackgroundInnerColor = rootElement.findName("prevImageBackgroundInnerColor");
        this.prevImageStoryboardShow = rootElement.findName("prevImageStoryboardShow");
        this.prevImageStoryboardHide = rootElement.findName("prevImageStoryboardHide");

        this.slideTransform = rootElement.findName("SlideTransform");
        this.slideStoryboard = rootElement.findName("SlideStoryboard");
        this.slideKeyFrame1 = rootElement.findName("SlideKeyFrame1");
        this.slideKeyFrame2 = rootElement.findName("SlideKeyFrame2");

        this.buttonPrevPage = rootElement.findName("buttonPrevPage");
        this.buttonPrev = rootElement.findName("buttonPrev");
        this.buttonPause = rootElement.findName("buttonPause");
        this.buttonPlay = rootElement.findName("buttonPlay");
        this.playStoryboard = rootElement.findName("playStoryboard");
        this.buttonNext = rootElement.findName("buttonNext");
        this.buttonNextPage = rootElement.findName("buttonNextPage");
        this.buttonFullScreen = rootElement.findName("buttonFullScreen");
        this.buttonResize = rootElement.findName("buttonResize");
        this.buttonSave = rootElement.findName("buttonSave");

        this.imageFolder = this.getValue(userContext, "imageFolder", "Images/");

        this.buttonPrevPage.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonPrevPage_MouseLeftButtonDown));
        this.buttonPrev.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonPrev_MouseLeftButtonDown));
        this.buttonPause.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonPause_MouseLeftButtonDown));
        this.buttonPlay.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonPlay_MouseLeftButtonDown));
        this.buttonNext.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonNext_MouseLeftButtonDown));
        this.buttonNextPage.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonNextPage_MouseLeftButtonDown));
        this.buttonFullScreen.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonFullScreen_MouseLeftButtonDown));
        this.buttonResize.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonResize_MouseLeftButtonDown));
        this.buttonSave.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.buttonSave_MouseLeftButtonDown));

        var delEnter = Silverlight.createDelegate(this, this.button_MouseEnter);
        var delLeave = Silverlight.createDelegate(this, this.button_MouseLeave);
        this.buttonPrevPage.addEventListener("MouseEnter", delEnter);
        this.buttonPrevPage.addEventListener("MouseLeave", delLeave);
        this.buttonPrev.addEventListener("MouseEnter", delEnter);
        this.buttonPrev.addEventListener("MouseLeave", delLeave);
        this.buttonPause.addEventListener("MouseEnter", delEnter);
        this.buttonPause.addEventListener("MouseLeave", delLeave);
        this.buttonPlay.addEventListener("MouseEnter", delEnter);
        this.buttonPlay.addEventListener("MouseLeave", delLeave);
        this.buttonNext.addEventListener("MouseEnter", delEnter);
        this.buttonNext.addEventListener("MouseLeave", delLeave);
        this.buttonNextPage.addEventListener("MouseEnter", delEnter);
        this.buttonNextPage.addEventListener("MouseLeave", delLeave);
        this.buttonFullScreen.addEventListener("MouseEnter", delEnter);
        this.buttonFullScreen.addEventListener("MouseLeave", delLeave);
        this.buttonResize.addEventListener("MouseEnter", delEnter);
        this.buttonResize.addEventListener("MouseLeave", delLeave);
        this.buttonSave.addEventListener("MouseEnter", delEnter);
        this.buttonSave.addEventListener("MouseLeave", delLeave);

        this.nextImageActionPane.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.nextImagePane_MouseLeftButtonDown));
        this.nextImageActionPane.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.nextImagePane_MouseEnter));
        this.nextImageActionPane.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.nextImagePane_MouseLeave));
        this.prevImageActionPane.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.prevImagePane_MouseLeftButtonDown));
        this.prevImageActionPane.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.prevImagePane_MouseEnter));
        this.prevImageActionPane.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.prevImagePane_MouseLeave));


        this.captionPaneAction.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.captionPaneAction_MouseEnter));
        this.captionPaneAction.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.captionPaneAction_MouseLeave));
        this.captionPaneAction.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.captionPaneAction_MouseLeftButtonDown));

        this.controlPane.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.controlPane_MouseEnter));
        this.controlPane.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.controlPane_MouseLeave));

        this.controlBackground.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.controlBackground_MouseLeftButtonDown));

        this.slideSettings = { total: 0 };
        this.selectedThumbnailBorderColor = "White";
        this.slideIndex = -1;
        this.slideInfos = new Array();
        this.pages = new Array();
        this.buttonOptions = BUTTON_NONE;
        this.autoPlay = true;
        this.padding = 8;

        this.thumbnailWidth = 50;
        this.thumbnailHeight = 50;
        this.thumbnailRadiusX = 4;
        this.thumbnailRadiusY = 4;

        this.captionAutoHide = true;
        this.controlAutoHide = true;

        this.animateCaptionByOpacity = true;

        this.stop(STATE_STOPPED);
        this.showProgress(0);

        // create slideshow        
        this.createSlideshow(userContext);
    },

    onResized: function(sender, eventArgs)
    {
        this.updateLayout(this.control.content.actualWidth, this.control.content.actualHeight);
    },

    onFullResized: function(sender, eventArgs)
    {
        this.updateLayout(this.control.content.actualWidth, this.control.content.actualHeight);

        if (this.control.content.fullScreen)
        {
            this.buttonResize.visibility = "Visible";
            this.buttonFullScreen.visibility = "Collapsed";
            this.buttonSave.visibility = "Collapsed";
            this.content.background = this.contentBackgroundFullscreenColor;
        }
        else
        {
            this.buttonFullScreen.visibility = "Visible";
            if ((this.buttonOptions & BUTTON_SAVE) > 0)
            {
                this.buttonSave.visibility = "Visible";
            }
            this.buttonResize.visibility = "Collapsed";
            this.content.background = this.contentBackgroundColor;
        }
    },

    updateLayout: function(width, height)
    {
        width = Math.max(width, 116);
        height = Math.max(height, 116);

        this.background.width = width;
        this.background.height = height;

        var contentHeight = height - 2 * this.padding;

        var controlPaneTop = height;
        //alert("height: " + height);
        var thumbnailsPaneTop = 5;
        var buttonPaneTop = 0;
        var trackerPaneTop = Math.floor(this.buttonPane.height / 2);
        var controlPaneHeight = 13;


        //        var buttonTop = height - this.padding;
        //        var buttonHeight = this.trackerPane.Height;
        //        if (this.buttonOptions > 0 || this.trackerPane.visibility == "Visible")
        //        {
        //            contentHeight -= (20 + this.padding);
        //            buttonTop -= 20;
        //        }

        if (this.thumbnailsPane.visibility == "Collapsed" && this.buttonOptions == 0 && this.trackerPane.visibility == "Collapsed")
        {
            this.controlPane.visibility = "Collapsed";
        }
        else
        {
            if (this.thumbnailsPane.visibility == "Visible")
            {
                //contentHeight -= (48 + this.padding);
                controlPaneHeight += this.thumbnailHeight;
                buttonPaneTop = thumbnailsPaneTop + this.thumbnailHeight + 5;
                trackerPaneTop = buttonPaneTop;
            }

            if (this.buttonOptions > 0)
            {
                if (this.trackerPane.visibility == "Visible")
                {
                    if (this.tracker.actualHeight < this.buttonPane.height)
                    {
                        controlPaneHeight += this.buttonPane.height;
                    }
                    else
                    {
                        controlPaneHeight += this.tracker.actualHeight;
                    }
                }
                else
                {
                    controlPaneHeight += this.buttonPane.height;
                }
            }
            else if (this.trackerPane.visibility == "Visible")
            {
                controlPaneHeight += this.tracker.actualHeight;
            }

            controlPaneTop = height - controlPaneHeight - 2 * this.padding;
        }

        this.content.setValue("Canvas.Left", this.padding);
        this.content.setValue("Canvas.Top", this.padding);
        this.content.width = width - 2 * this.padding;
        this.content.height = contentHeight;
        this.contentClip.rect = "0,0," + this.content.width + "," + this.content.height;

        this.progressPane.setValue("Canvas.Top", this.content.height / 2);
        this.progressPane.setValue("Canvas.Left", Math.floor(width / 2 - this.progressPane.width / 2));
        this.errorPane.setValue("Canvas.Left", (this.content.width - this.errorPane.width) / 2);

        this.errorPane.setValue("Canvas.Top", (this.content.height - this.errorPane.height) / 2);
        this.errorPane.setValue("Canvas.Left", (this.content.width - this.errorPane.width) / 2);

        this.controlPane.setValue("Canvas.Top", controlPaneTop);
        this.controlPane.width = this.content.width;
        this.controlPane.height = controlPaneHeight;
        if (!this.controlAutoHide)
            this.controlPane.opacity = 1;

        //this.trackerPane.setValue("Canvas.Top", height - 20 - this.padding);
        this.trackerPane.setValue("Canvas.Top", trackerPaneTop);
        //alert("controlPaneHeight: " + controlPaneHeight);
        //alert("controlPaneTop: " + controlPaneTop);

        this.buttonPane.setValue("Canvas.Left", Math.floor(this.controlPane.width / 2));
        this.buttonPane.setValue("Canvas.Top", buttonPaneTop);

        //this.thumbnails.setValue("Canvas.Top", buttonTop - 48 - this.padding);
        this.thumbnailsPane.setValue("Canvas.Top", thumbnailsPaneTop);
        this.thumbnailsPane.height = this.thumbnailHeight - 2;
        this.thumbnailsPane.width = this.thumbnailWidth - 2;

        if (this.animateCaptionByOpacity)
        {
            this.captionPaneCavasTop = 0;
            this.captionPane.opacity = 0;
        }
        else
        {
            this.captionPaneCavasTop = -100;
            this.captionPane.opacity = 1;
        }
        this.captionPane.setValue("Canvas.Top", this.captionPaneCavasTop);
        this.captionPane.width = this.content.width;
        this.caption.width = this.content.width;
        this.caption.text = this.caption.text;
        if (!this.captionAutoHide)
        {
            if (this.animateCaptionByOpacity)
                this.captionStoryboardShow.begin();
            else
                this.captionPaneSlideIn();
        }


        this.captionPaneRectangleAction.width = this.content.width;
        this.captionPaneRectangleAction.height = Math.floor(this.content.width / 6);

        this.captionBackground.width = this.content.width;

        if (!this.captionVisible)
        {
            this.captionPane.visibility = "Collapsed";
        }

        this.updateCaptionLayout();
        this.updateControlLayout();
        this.updateSideLayout();

        var infos = this.getLoadedSlideInfos();
        for (var i = 0; i < infos.length; i++)
        {
            var captionHeight = this.getCaptionHeight(infos[i]);
            infos[i].slide.resize(this.content.width, this.content.height - captionHeight);
        }

        this.updateThumbnails(true)
    },

    updateCaptionLayout: function()
    {
        //var captionBottom = this.content.height;
        var captionHeight = this.captionVisible && this.caption.text ? this.caption.actualHeight + 4 : 0;
        var captionWidth = this.captionVisible && this.caption.text ? this.caption.actualWidth : 0;

        if (captionHeight == 0)
        {
            this.captionBackground.height = 0;
            return;
        }

        this.captionBackground.height = captionHeight + 10;

        //this.captionPane.height = captionHeight;
        this.captionPaneClip.rect = "0,0," + this.captionPane.width + "," + this.captionBackground.height;
        this.caption.height = captionHeight > 0 ? captionHeight - 4 : 0;

        this.caption.setValue("Canvas.Left", (this.content.width - captionWidth) / 2)
        //this.captionPane.setValue("Canvas.Top", captionBottom - captionHeight);

    },

    updateControlLayout: function()
    {

        this.controlPaneClip.rect = "0,0," + this.controlPane.width + "," + this.controlPane.height; //captionHeight;

        this.controlBackground.height = this.controlPane.height;
        this.controlBackground.width = this.controlPane.width;

    },

    updateSideLayout: function()
    {
        var widthSide = Math.floor(this.content.width / 7);
        var heightSide = Math.floor(this.content.height / 2);
        var triangleHeight = 46; //Math.floor(heightSide / 5);
        var triangleWidth = 30;

        //alert(widthSide);
        //widthSide = Math.min(widthSide, 60);
        //alert("po: "+widthSide);

        this.nextImageActionPane.width = widthSide;
        this.nextImageActionPane.setValue("Canvas.Left", this.content.width - this.nextImageActionPane.width);
        this.nextImageActionPane.height = heightSide;
        this.nextImageActionPane.setValue("Canvas.Top", Math.floor((this.content.height - this.nextImageActionPane.height) / 2));

        this.nextImagePane.width = 55;
        this.nextImagePane.setValue("Canvas.Left", this.content.width - this.nextImagePane.width);
        this.nextImagePane.height = heightSide;
        this.nextImagePane.setValue("Canvas.Top", Math.floor((this.content.height - this.nextImagePane.height) / 2));

        this.nextImageBackground.width = this.nextImagePane.width;
        this.nextImageBackground.height = this.nextImagePane.height;

        var padding = 10; // odsazeni od okraje

        //var A = Math.floor(widthSide / 2).toString() + "," + Math.floor(heightSide / 2 - triangleHeight / 2).toString();
        var A = Math.floor(this.nextImagePane.width - triangleWidth).toString() + "," + Math.floor(this.nextImagePane.height / 2 - triangleHeight / 2).toString();
        var B = (this.nextImagePane.width - padding).toString() + "," + Math.floor(this.nextImagePane.height / 2).toString();
        //var C = Math.floor(widthSide / 2).toString() + "," + Math.floor(heightSide / 2 + triangleHeight / 2).toString();
        var C = Math.floor(this.nextImagePane.width - triangleWidth).toString() + "," + Math.floor(this.nextImagePane.height / 2 + triangleHeight / 2).toString();

        this.nextImageBackgroundTriangle.points = A + " " + B + " " + C;


        this.prevImageActionPane.width = this.nextImageActionPane.width;
        this.prevImageActionPane.setValue("Canvas.Left", 0);
        this.prevImageActionPane.height = this.nextImageActionPane.height
        this.prevImageActionPane.setValue("Canvas.Top", this.nextImageActionPane["Canvas.Top"]);

        this.prevImagePane.width = this.nextImagePane.width;
        this.prevImagePane.setValue("Canvas.Left", 0);
        this.prevImagePane.height = this.nextImagePane.height;
        this.prevImagePane.setValue("Canvas.Top", this.nextImagePane["Canvas.Top"]);

        this.prevImageBackground.width = this.prevImagePane.width;
        this.prevImageBackground.height = this.prevImagePane.height;

        A = padding.toString() + "," + Math.floor(this.prevImagePane.height / 2).toString();
        //B = Math.floor(widthSide / 2).toString() + "," + Math.floor(heightSide / 2 - triangleHeight / 2).toString();
        B = Math.floor(triangleWidth).toString() + "," + Math.floor(this.prevImagePane.height / 2 - triangleHeight / 2).toString();
        //C = Math.floor(widthSide / 2).toString() + "," + Math.floor(heightSide / 2 + triangleHeight / 2).toString();
        C = Math.floor(triangleWidth).toString() + "," + Math.floor(this.prevImagePane.height / 2 + triangleHeight / 2).toString();

        this.prevImageBackgroundTriangle.points = A + " " + B + " " + C;


    },

    updateThumbnails: function(force)
    {
        if (this.thumbnailsPane.visibility == "Collapsed")
        {
            return;
        }

        var thumbnailCount = Math.floor((this.content.width + 8) / (this.thumbnailWidth + 6));
        var startIndex = Math.floor(this.slideIndex / thumbnailCount) * thumbnailCount;

        if (this.slideIndex == -1)
        {
            startIndex = 0;
        }

        if (force || this.getThumbnail(startIndex) == null)
        {
            this.thumbnailsPane.children.clear();
        }
        var x = 0;
        var dummySlideInfo = new SlideInfo();
        for (var i = startIndex; i < Math.min(startIndex + thumbnailCount, this.slideSettings.total); i++)
        {
            var slideInfo = this.slideInfos[i];
            if (!slideInfo)
            {
                // another page is needed
                this.loadSlidesForIndex(i);

                // for now use dummy slideinfo
                slideInfo = dummySlideInfo;
            }
            var url = slideInfo.getThumbnailUrl();
            var thumbnailName = this.getThumbnailName(i);
            var thumbnailImageName = this.getThumbnailImageName(i);

            var thumbnail = this.getThumbnail(i);
            if (thumbnail == null)
            {

                var xaml = '<Canvas>' +
                            '  <Rectangle Canvas.Left="' + x + '" Width="' + (this.thumbnailWidth - 2).toString() + '" Height="' + (this.thumbnailHeight - 2).toString() + '" RadiusX="' + this.thumbnailRadiusX.toString() + '" RadiusY="' + this.thumbnailRadiusY.toString() + '" Fill="Black"/>' +
                            '  <Rectangle Name="' + thumbnailName + '" Canvas.Left="' + (x - 1) + '" Canvas.Top="-1" Width="' + this.thumbnailWidth.toString() + '" Height="' + this.thumbnailHeight.toString() + '" Opacity="0" RadiusX="' + this.thumbnailRadiusX.toString() + '" RadiusY="' + this.thumbnailRadiusY.toString() + '" Stroke="#00000000" StrokeThickness="2" Cursor="Hand">' +
                            '    <Rectangle.Resources>' +
                            '      <Storyboard Name="story' + thumbnailImageName + '">' +
                            '        <DoubleAnimation ' +
                            '          Storyboard.TargetName="' + thumbnailName + '" ' +
                            '          Storyboard.TargetProperty="Opacity" ' +
                            '          Duration="0:0:0.5" ' +
                            '          To="0.5"/>' +
                            '      </Storyboard>' +
                            '    </Rectangle.Resources>' +
                            '    <Rectangle.Fill>' +
                            '      <ImageBrush Name="' + thumbnailImageName + '" Stretch="UniformToFill" ';
                if (url)
                {
                    xaml += '        ImageSource="' + url + '"';
                }
                xaml += ' /> </Rectangle.Fill>' +
                            '  </Rectangle></Canvas>';

                this.thumbnailsPane.children.add(this.control.content.createFromXaml(xaml));
                thumbnail = this.getThumbnail(i);

                thumbnail.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.thumbnail_MouseEnter));
                thumbnail.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.thumbnail_MouseLeave));
                thumbnail.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.thumbnail_MouseLeftButtonDown));
                thumbnail.fill.addEventListener("ImageFailed", Silverlight.createDelegate(this, this.thumbnail_ImageFailed));
                thumbnail.fill.addEventListener("DownloadProgressChanged", Silverlight.createDelegate(this, this.thumbnail_DownloadProgressChanged));
            }
            else if (!thumbnail.fill.imageSource)
            {
                thumbnail.fill.imageSource = url;
            }

            if (thumbnail.fill.downloadProgress == 1.0)
            {
                this.thumbnail_DownloadProgressChanged(thumbnail.fill, null);
            }

            if (i == this.slideIndex)
            {
                thumbnail.stroke = this.selectedThumbnailBorderColor;
            }

            x += this.thumbnailWidth + 6;
        }
    },

    selectThumbnail: function(index, select)
    {
        if (this.thumbnailsPane.visibility == "Collapsed")
        {
            return;
        }

        var thumbnail = this.getThumbnail(index);
        if (thumbnail)
        {
            thumbnail.stroke = select ? this.selectedThumbnailBorderColor : "#00000000";
        }
        else if (select)
        {
            this.updateThumbnails(false);
        }
    },

    showProgress: function(progress)
    {
        this.progress.width = progress * 100;
        if (progress < 1)
        {
            this.progressIn.begin();
        }
        else
        {
            this.progressOut.begin();
        }
    },

    getPrevSlideIndex: function()
    {
        var index = this.slideIndex - 1;
        if (index < 0)
        {
            index = this.slideSettings.total - 1;
        }
        return index;
    },

    getNextSlideIndex: function()
    {
        var index = this.slideIndex + 1;
        if (index >= this.slideSettings.total)
        {
            index = 0;
        }
        return index
    },

    loadSlide: function(slideInfo)
    {
        if (!slideInfo.slide)
        {
            //var captionHeight = this.getCaptionHeight(slideInfo);
            slideInfo.slide = new Slide(this.control, slideInfo, this.content.width, this.content.height, this.getImageUrl('warning.png'));
            slideInfo.slide.stateChanged = Silverlight.createDelegate(this, this.slide_stateChanged);

            this.content.children.add(slideInfo.slide.content);
        }
    },

    unloadSlide: function(slideInfo)
    {
        this.content.children.remove(slideInfo.slide.content);

        slideInfo.slide.unload();
        slideInfo.slide.stateChanged = null;
        slideInfo.slide = null;
    },

    showSlide: function(index, repaint)
    {
        if (index != this.slideIndex || repaint)
        {
            // unselect current thumbnail
            this.selectThumbnail(this.slideIndex, false);
        }

        var slideInfo = this.getSlideInfo(index);
        if (slideInfo)
        {
            if (index != this.slideIndex || repaint)
            {
                if (this.state != STATE_STOPPED)
                {
                    var currentSlideInfo = this.getSlideInfo(this.slideIndex);
                    if (currentSlideInfo && currentSlideInfo.slide)
                    {
                        currentSlideInfo.slide.hide(false);
                    }
                }

                this.slideIndex = index;

                // select new slide
                if (slideInfo.slide)
                {
                    slideInfo.slide.show();
                }
                else
                {
                    this.showProgress(0);
                    this.loadSlide(slideInfo);
                }
            }
        }
        else
        {
            this.slideIndex = index;
            this.loadSlidesForIndex(index);
        }

        this.selectThumbnail(this.slideIndex, true);
        var msg = "No slides found";
        if (this.slideSettings.total > 0)
        {
            //msg = "Slide " + (this.slideIndex + 1) + " of " + this.slideSettings.total;
            msg = (this.slideIndex + 1) + " z " + this.slideSettings.total;
        }
        this.tracker.Text = msg;
    },

    slide_stateChanged: function(sender, slideState, progress)
    {
        var currentSlideInfo = this.getSlideInfo(this.slideIndex);
        var isCurrent = currentSlideInfo == sender.slideInfo;

        if (slideState == SLIDESTATE_LOADING)
        {
            if (isCurrent)
            {
                this.showProgress(progress);
            }
        }
        else if (slideState == SLIDESTATE_LOADED)
        {
            if (isCurrent)
            {
                this.showProgress(1);
                sender.show();
            }
        }
        else if (slideState == SLIDESTATE_SHOWING)
        {
            if (this.state == STATE_RUNNING)
            {
                // preload next slide
                var nextIndex = this.getNextSlideIndex();
                var nextSlideInfo = this.getSlideInfo(nextIndex);
                if (nextSlideInfo)
                {
                    this.loadSlide(nextSlideInfo);
                }
            }

            this.caption.text = currentSlideInfo.caption;
            this.updateCaptionLayout();

            //this.captionStoryboardShow.begin();

        }
        else if (slideState == SLIDESTATE_SHOWED)
        {
            if (isCurrent && this.state == STATE_RUNNING)
            {
                var index = this.getNextSlideIndex();
                if (index != this.slideIndex)
                {
                    this.showSlide(index);
                }
            }
        }
        else if (slideState == SLIDESTATE_HIDDEN)
        {
            this.unloadSlide(sender.slideInfo);

        }
    },

    thumbnail_MouseEnter: function(sender, eventArgs)
    {
        sender.opacity = 1
    },

    thumbnail_MouseLeave: function(sender, eventArgs)
    {
        sender.opacity = 0.5
    },

    thumbnail_MouseLeftButtonDown: function(sender, eventArgs)
    {
        var index = this.getIndexFromName(sender.name);
        if (index != this.slideIndex)
        {
            this.stop(STATE_STOPPED);
            this.showSlide(index);
        }
    },

    thumbnail_DownloadProgressChanged: function(sender, eventArgs)
    {
        if (sender.downloadProgress == 1.0)
        {
            var storyboard = this.content.FindName("story" + sender.name);
            if (storyboard)
            {
                storyboard.begin();
            }
        }
    },

    thumbnail_ImageFailed: function(sender, eventArgs)
    {
        if (sender.stretch != "None")
        {
            sender.stretch = "None";
            sender.ImageSource = this.getImageUrl('warning.png');
        }
    },

    buttonPrevPage_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);

        var thumbnailCount = Math.floor((this.content.width + 8) / 56);
        var index = Math.floor((this.slideIndex - thumbnailCount) / thumbnailCount) * thumbnailCount;

        if (index < 0)
        {
            var offset = this.slideSettings.total % thumbnailCount;
            if (offset == 0)
            {
                offset = thumbnailCount;
            }
            index = this.slideSettings.total - offset;
        }

        this.showSlide(index);
    },

    buttonPrev_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);
        this.showSlide(this.getPrevSlideIndex());
    },

    prevImagePane_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);
        this.showSlide(this.getPrevSlideIndex());
    },

    buttonPause_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total == 0) { return; }
        this.stop(STATE_PAUSED);
    },

    buttonPlay_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total == 0) { return; }
        this.play();
    },

    buttonNext_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);

        this.showSlide(this.getNextSlideIndex());
    },

    nextImagePane_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);

        this.showSlide(this.getNextSlideIndex());
    },

    buttonNextPage_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (this.slideSettings.total < 2) { return; }
        this.stop(STATE_STOPPED);

        var thumbnailCount = Math.floor((this.content.width + 8) / 56);
        var index = Math.floor((this.slideIndex + thumbnailCount) / thumbnailCount) * thumbnailCount;

        if (index >= this.slideSettings.total)
        {
            index = 0;
        }

        this.showSlide(index);
    },

    buttonFullScreen_MouseLeftButtonDown: function(sender, eventArgs)
    {
        this.control.content.fullScreen = true;

        this.button_MouseLeave(sender, eventArgs);   // enforce mouse leave repaint
    },

    buttonResize_MouseLeftButtonDown: function(sender, eventArgs)
    {      
        this.control.content.fullScreen = false;

        this.button_MouseLeave(sender, eventArgs);   // enforce mouse leave repaint
    },

    buttonSave_MouseLeftButtonDown: function(sender, eventArgs)
    {
        var slideInfo = this.getSlideInfo(this.slideIndex);
        if (slideInfo)
        {
            window.open(slideInfo.getImageUrl());
        }
    },

    stop: function(stopState)
    {
        this.state = stopState;
        this.buttonPlay.visibility = "Visible";
        this.playStoryboard.begin();
        this.buttonPause.visibility = "Collapsed";

        this.button_MouseLeave(this.buttonPlay, null);   // enforce mouse leave repaint

        var infos = this.getLoadedSlideInfos();
        for (var i = 0; i < infos.length; i++)
        {
            if (stopState == STATE_PAUSED)
            {
                infos[i].slide.pause();
            }
            else
            {
                infos[i].slide.hide(true);
            }
        }
    },

    play: function()
    {
        if (this.state != STATE_RUNNING)
        {
            if ((this.buttonOptions & BUTTON_PLAYPAUSE) > 0)
            {
                this.buttonPause.visibility = "Visible";
            }
            this.buttonPlay.visibility = "Collapsed";
            this.playStoryboard.stop();

            var infos = this.getLoadedSlideInfos();
            for (var i = 0; i < infos.length; i++)
            {
                infos[i].slide.resume();
            }

            var stopped = this.state == STATE_STOPPED;

            this.state = STATE_RUNNING;

            if (stopped)
            {
                this.showSlide(this.getNextSlideIndex());
            }
        }
    },
    setButtonColors: function(btn, backColor, foreColor, borderColor)
    {
        var rect = btn.children.getItem(0);
        rect.fill = backColor;
        rect.stroke = borderColor;

        for (var i = 1; i < btn.children.count; i++)
        {
            var shape = btn.children.getItem(i);
            if (shape.fill) shape.fill = foreColor;
            if (shape.stroke) shape.stroke = foreColor;
        }
    },
    getIndexFromName: function(name)
    {
        var i = name.lastIndexOf('.');
        if (i != -1)
        {
            return parseInt(name.substr(i + 1));
        }
        return -1;
    },

    getLoadedSlideInfos: function()
    {
        var infos = new Array();
        for (var i = 0; i < this.slideSettings.total; i++)
        {
            var slideInfo = this.slideInfos[i];
            if (slideInfo && slideInfo.slide)
            {
                infos.push(slideInfo);
            }
        }

        return infos;
    },

    getSlideInfo: function(index)
    {
        if (index >= 0 && index < this.slideInfos.length)
        {
            return this.slideInfos[index];
        }
        return null;
    },

    getThumbnailName: function(index)
    {
        return "thumbnail." + index;
    },

    getThumbnailImageName: function(index)
    {
        return "thumbnailImage." + index;
    },

    getThumbnail: function(index)
    {
        var thumbnailName = this.getThumbnailName(index);
        return this.content.FindName(thumbnailName);
    },
    getImageUrl: function(image)
    {
        return this.imageFolder + image;
    },
    loadSlides: function(url, page)
    {
        if (url.substr(0, 1) == "#")
        {
            // inline xml
            var id = url.substr(1);
            var element = document.getElementById(id);
            if (element)
            {
                this.pages[1] = true;
                this.addSlides(this.createDocument(element.innerHTML));
            }
            else
            {
                throw "Element " + id + " not found";
            }
        }
        else
        {
            if (page)
            {
                url += (url.indexOf("?") == -1) ? "?" : "&";
                url += "page=" + page;
            }
            else
            {
                page = 1;
            }

            if (!this.pages[page])
            {
                this.pages[page] = true;
                this.loadXml(url, Silverlight.createDelegate(this, this.onloadSlides));
            }
        }
    },

    loadSlidesForIndex: function(slideIndex)
    {
        if (slideIndex >= 0 && slideIndex < this.slideSettings.total && this.slidesSource)
        {
            var page = Math.floor(slideIndex / this.slideSettings.pageSize) + 1;

            this.loadSlides(this.slidesSource, page);
        }
    },

    createSlideshow: function(settings)
    {
        try
        {
            this.rootElement.visibility = "Visible";

            this.imageFolder = this.getValue(settings, "imageFolder", "Images/");

            // apply slideshow settings
            this.thumbnailsPane.visibility = this.getValue(settings, "thumbnailsVisible", true) ? "Visible" : "Collapsed";
            this.trackerPane.visibility = this.getValue(settings, "trackerVisible", true) ? "Visible" : "Collapsed";
            this.tracker.foreground = this.getValue(settings, "trackerForeground", "Silver");
            this.tracker.fontFamily = this.getValue(settings, "trackerFontFamily", "Verdana");
            this.tracker.fontSize = this.getValue(settings, "trackerFontSize", 11);
            this.tracker.fontStyle = this.getValue(settings, "trackerFontStyle", "Normal");
            this.tracker.fontWeight = this.getValue(settings, "trackerFontWeight", "Normal");
            this.selectedThumbnailBorderColor = this.getValue(settings, "selectedThumbnailBorderColor", this.selectedThumbnailBorderColor);
            this.background.fill = this.getValue(settings, "background", "#202020");
            this.captionVisible = this.getValue(settings, "captionVisible", true);
            this.captionAutoHide = this.getValue(settings, "captionAutoHide", true);
            this.controlAutoHide = this.getValue(settings, "controlAutoHide", true);
            this.captionBackgroundColorTop.Color = this.getValue(settings, "captionBackgroundTop", "Silver");
            this.captionBackgroundColorBottom.Color = this.getValue(settings, "captionBackgroundBottom", "Transparent");
            this.controlBackgroundColorTop.Color = this.getValue(settings, "controlBackgroundTop", "Transparent");
            this.controlBackgroundColorBottom.Color = this.getValue(settings, "controlBackgroundBottom", "Silver");
            this.controlAutoHide = this.getValue(settings, "controlAutoHide", true);
            this.caption.foreground = this.getValue(settings, "captionForeground", "White");
            this.caption.fontFamily = this.getValue(settings, "captionFontFamily", "Verdana");
            this.caption.fontSize = this.getValue(settings, "captionFontSize", 11);
            this.caption.fontStyle = this.getValue(settings, "captionFontStyle", "Normal");
            this.caption.fontWeight = this.getValue(settings, "captionFontWeight", "Bold");
            this.animateCaptionByOpacity = this.getValue(settings, "animateCaptionByOpacity", true);
            this.defaultCaptionHeight = this.caption.fontSize + 4;
            this.captionBackground.opacity = this.getValue(settings, "captionOpacity", .7);
            this.controlBackground.opacity = this.getValue(settings, "controlOpacity", .7);
            var borderRadius = this.getValue(settings, "borderRadius", 8);
            this.background.radiusX = borderRadius;
            this.background.radiusY = borderRadius;
            this.contentClip.radiusX = borderRadius;
            this.contentClip.radiusY = borderRadius;
            this.contentBackgroundColor = this.getValue(settings, "contentBackground", "Black");
            this.contentBackgroundFullscreenColor = this.getValue(settings, "contentBackgroundFullscreen", "Gray");
            this.content.background = this.contentBackgroundColor;

            this.buttonOptions = this.getValue(settings, "buttonOptions", BUTTON_ALL);
            this.buttonPane.visibility = (this.buttonOptions > 0) ? "Visible" : "Collapsed";
            this.padding = this.getValue(settings, "padding", 8);
            this.autoPlay = this.getValue(settings, "autoPlay", true);
            var sID = this.getValue(settings, "slideStartIndex", -1);
            this.slideIndex = sID < 0 ? sID : sID - 1;

            var outerTriangleColor = this.getValue(settings, "sideControlBackgroundTriangleOuter", "White");
            var innerTriangleColor = this.getValue(settings, "sideControlBackgroundTriangleInner", "Gray");

            var outerColor = this.getValue(settings, "sideControlBackgroundOuter", "Silver");
            var innerColor = this.getValue(settings, "sideControlBackgroundInner", "Transparent");

            this.nextImageBackgroundOuterColor.Color = outerColor;
            this.nextImageBackgroundInnerColor.Color = innerColor;
            this.nextImageBackgroundTriangleOuterColor.Color = outerTriangleColor;
            this.nextImageBackgroundTriangleInnerColor.Color = innerTriangleColor;

            this.prevImageBackgroundOuterColor.Color = outerColor;
            this.prevImageBackgroundInnerColor.Color = innerColor;
            this.prevImageBackgroundTriangleOuterColor.Color = outerTriangleColor;
            this.prevImageBackgroundTriangleInnerColor.Color = innerTriangleColor;

            var opacitySide = this.getValue(settings, "sideControlOpacity", .1);
            this.nextImageBackground.Opacity = opacitySide;
            this.prevImageBackground.Opacity = opacitySide;

            var opacityTriangleSide = this.getValue(settings, "sideControlTriangleOpacity", .7);
            this.nextImageBackgroundTriangle.Opacity = opacityTriangleSide;
            this.prevImageBackgroundTriangle.Opacity = opacityTriangleSide;

            this.thumbnailWidth = this.getValue(settings, "thumbnailWidth", 50);
            this.thumbnailHeight = this.getValue(settings, "thumbnailHeight", 50);
            this.thumbnailRadiusX = this.getValue(settings, "thumbnailRadiusX", 4);
            this.thumbnailRadiusY = this.getValue(settings, "thumbnailRadiusY", 4);


            var btnBackground = this.getValue(settings, "buttonBackground", "Black");
            var btnForeground = this.getValue(settings, "buttonForeground", "White");
            var btnPlayForeground = this.getValue(settings, "buttonPlayForeground", "LightGreen");
            var btnBorder = this.getValue(settings, "buttonBorderColor", "White");

            this.setButtonColors(this.buttonPrevPage, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonPrev, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonPause, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonPlay, btnBackground, btnPlayForeground, btnBorder);
            this.setButtonColors(this.buttonNext, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonNextPage, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonFullScreen, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonResize, btnBackground, btnForeground, btnBorder);
            this.setButtonColors(this.buttonSave, btnBackground, btnForeground, btnBorder);

            if ((this.buttonOptions & BUTTON_PLAYPAUSE) == 0)
            {
                this.buttonPlay.visibility = "Collapsed";
                this.buttonPause.visibility = "Collapsed";
            }
            if ((this.buttonOptions & BUTTON_PREVNEXT) == 0)
            {
                this.buttonPrev.visibility = "Collapsed";
                this.buttonNext.visibility = "Collapsed";
            }
            if ((this.buttonOptions & BUTTON_PREVNEXTPAGE) == 0)
            {
                this.buttonPrevPage.visibility = "Collapsed";
                this.buttonNextPage.visibility = "Collapsed";
            }
            if ((this.buttonOptions & BUTTON_FULLSCREEN) == 0)
            {
                this.buttonFullScreen.visibility = "Collapsed";
            }
            if ((this.buttonOptions & BUTTON_SAVE) == 0)
            {
                this.buttonSave.visibility = "Collapsed";
            }
            this.onResized();

            if (!settings.slideSettings) { settings.slideSettings = {} };

            this.slideSettings = {
                total: 0,
                theme: this.getValue(settings.slideSettings, "theme", THEME_NONE),
                speedRatio: this.getValue(settings.slideSettings, "speedRatio", 1),
                duration: this.getValue(settings.slideSettings, "duration", "0:0:5"),
                endDelay: this.getValue(settings.slideSettings, "endDelay", "0:0:0"),
                animationBegin: this.getValue(settings.slideSettings, "animationBegin", ANIMATION_FADE),
                animationEnd: this.getValue(settings.slideSettings, "animationEnd", ANIMATION_FADE),
                centerX: this.getValue(settings.slideSettings, "centerX", 0),
                centerY: this.getValue(settings.slideSettings, "centerY", 0),
                scale: this.getValue(settings.slideSettings, "scale", 1),
                rotateAngle: this.getValue(settings.slideSettings, "rotateAngle", 0),
                borderVisible: this.getValue(settings.slideSettings, "borderVisible", false),
                borderColor: this.getValue(settings.slideSettings, "borderColor", "White"),
                borderWidth: this.getValue(settings.slideSettings, "borderWidth", 4),
                borderRadius: this.getValue(settings.slideSettings, "borderRadius", 4)
            };
            this.slidesSource = this.getValue(settings, "slidesSource", "images.xml");
            this.loadSlides(this.slidesSource);
        }
        catch (e)
        {
            var details = e.description;
            if (!details)
            {
                details = e.toString();
            }
            this.showError("Slideshow settings not valid\n\n" + details);
        }
    },

    onloadSlides: function(sender, eventArgs)
    {
        try
        {
            this.addSlides(this.createDocument(sender.responseText));
        }
        catch (e)
        {
            var details = e.description;
            if (!details)
            {
                details = e.toString();
            }
            this.showError("Slideshow data not valid\n\n" + details);
        }
    },

    addSlides: function(doc)
    {
        try
        {
            var slidesNode = doc.getElementsByTagName("slides")[0];
            var slideNodes = doc.getElementsByTagName("slide");

            var total = Math.min(MAX_SLIDES, this.getIntAttribute(slidesNode, "total", slideNodes.length));
            var page = this.getIntAttribute(slidesNode, "page", 1);
            var pageSize = this.getIntAttribute(slidesNode, "pageSize", total);

            this.slideSettings.total = total;
            this.slideSettings.pageSize = pageSize;
            var startIndex = (page - 1) * pageSize;

            for (var i = 0; i < slideNodes.length; i++)
            {
                node = slideNodes[i];

                var imageUrl = node.getAttribute("imageUrl");
                var thumbnailUrl = node.getAttribute("thumbnailUrl");
                var caption = node.getAttribute("caption");

                var info = new SlideInfo(this.slideSettings, i, imageUrl, thumbnailUrl, caption);
                this.applyAttribute(slidesNode, info, "baseUrl");
                this.applyAttribute(node, info, "duration");
                this.applyAttribute(node, info, "endDelay");
                this.applyAttribute(node, info, "animationBegin");
                this.applyAttribute(node, info, "animationEnd");
                this.applyAttribute(node, info, "centerX");
                this.applyAttribute(node, info, "centerY");
                this.applyAttribute(node, info, "scale");
                this.applyAttribute(node, info, "rotateAngle");
                this.applyAttribute(node, info, "borderVisible", true);
                this.applyAttribute(node, info, "borderColor");
                this.applyAttribute(node, info, "borderWidth");
                this.applyAttribute(node, info, "borderRadius");

                if (info.animationBegin == ANIMATION_RANDOM)
                {
                    info.animationBegin = info.getRandomAnimation();
                }
                if (info.animationEnd == ANIMATION_RANDOM)
                {
                    info.animationEnd = info.getRandomAnimation();
                }

                this.slideInfos[startIndex + i] = info;
            }

            if (this.autoPlay)
            {
                if (this.slideIndex >= 0 && this.slideSettings.total > 1)
                    this.slideIndex = this.slideIndex - 1;

                this.play();
            }
            else
            {
                if (this.slideIndex == -1 && this.slideSettings.total > 1)
                {
                    this.slideIndex = 0;
                }
                if (this.slideIndex >= startIndex && this.slideIndex < startIndex + pageSize)
                {

                    this.showSlide(this.slideIndex, true);
                    this.updateThumbnails(false);

                }
                else
                {
                    this.updateThumbnails(false);
                }
            }
        }
        catch (e)
        {
            var details = e.description;
            if (!details)
            {
                details = e.toString();
            }
            this.showError("Failed to process loaded slides\n\n" + details);
        }
    },

    applyAttribute: function(node, info, name, isBool)
    {
        var value = node.getAttribute(name);
        if (value)
        {
            if (isBool)
            {
                info[name] = (value.toLowerCase() == "true");
            }
            else
            {
                info[name] = value;
            }
        }
    },

    getCaptionHeight: function(slideInfo)
    {
        return this.captionVisible && slideInfo.caption ? this.defaultCaptionHeight : 0;
    },

    getAttribute: function(node, name, defaultValue)
    {
        var value = node.getAttribute(name);
        if (value)
        {
            return value;
        }
        return defaultValue;
    },


    getIntAttribute: function(node, name, defaultValue)
    {
        var value = node.getAttribute(name);
        if (value)
        {
            return parseInt(value);
        }
        return defaultValue;
    },

    getValue: function(o, name, defaultValue)
    {
        if (o[name] == undefined)
        {
            return defaultValue;
        }
        return o[name];
    },

    loadXml: function(url, handler)
    {
        this.showProgress(0);
        var downloader = this.control.createObject("downloader");

        downloader.addEventListener("downloadProgressChanged", Silverlight.createDelegate(this, this.downloader_downloadProgressChanged));
        downloader.addEventListener("downloadFailed", Silverlight.createDelegate(this, this.downloader_downloadFailed));
        downloader.addEventListener("completed", handler);

        downloader.open("GET", url);
        downloader.send();
    },

    downloader_downloadProgressChanged: function(sender, eventArgs)
    {
        this.showProgress(sender.downloadProgress);
    },

    downloader_downloadFailed: function(sender, eventArgs)
    {
        this.showProgress(1);
        this.showError("Failed to load " + sender.uri + "\n\nHTTP status: " + sender.status + " " + sender.statusText);
    },

    createDocument: function(xml)
    {
        xml = xml.replace(/^\s+|\s+$/g, '');        //trim
        if (window.ActiveXObject)
        {
            var doc = new ActiveXObject("Microsoft.XMLDOM");
            if (!doc.loadXML(xml))
            {
                throw doc.parseError.reason;
            }
            return doc;
        }
        else
        {
            var parser = new DOMParser();
            return parser.parseFromString(xml, "text/xml");
        }
    },

    showError: function(msg)
    {
        var xaml =
            '<Canvas>' +
            '  <Image Source="' + this.getImageUrl('error.png') + '" />' +
            '  <TextBlock Name="textError" Canvas.Left="50" TextWrapping="Wrap" FontFamily="Verdana" FontSize="10" Foreground="Silver"></TextBlock>' +
            '</Canvas>';

        var canvas = this.control.content.createFromXaml(xaml, true);
        var textError = canvas.findName("textError");

        textError.text = msg;
        this.rootElement.visibility = "Visible";
        this.errorPane.width = Math.max(this.control.content.actualWidth - 20, 100);
        textError.width = this.errorPane.width - 50;
        this.errorPane.setValue("Canvas.Left", (this.control.content.actualWidth - this.errorPane.width) / 2);
        this.errorPane.children.add(canvas);
    },

    captionPaneAction_MouseEnter: function(sender, eventArgs)
    {

        if (this.animateCaptionByOpacity)
            this.captionStoryboardShow.begin();
        else
            this.captionPaneSlideIn();
    },

    captionPaneSlideIn: function()
    {
        if (this.captionBackground.height <= 0) { return; }

        // v xaml je nastavena nejaka minusova hodnota u objektu 'captionPane'
        // tak jeji kladna hodnota patri do promenne 'captionPaneCanvasTop'

        /// <summary>Slides the control into view.</summary>
        var start = this.slideTransform.y;
        var finish = Math.abs(this.captionPaneCavasTop) - this.captionBackground.height + this.captionBackground.height; //this.options.top;
        var distance = this.captionBackground.height;
        var duration = (finish - start) / distance; //this.options.slideAnimationDuration;
        //alert("this.captionBackground.height: " + this.captionBackground.height);
        //alert("start - finish: " + start + "    -    " + finish);
        //alert(duration);
        if (duration > 0)
        {
            this.slideKeyFrame1.value = start;
            this.slideKeyFrame2.value = finish;
            this.slideKeyFrame2.keyTime = "0:0:" + duration.toFixed(8);
            this.slideStoryboard.begin();
        }
    },

    captionPaneAction_MouseLeave: function(sender, eventArgs)
    {
        if (this.captionAutoHide)
        {
            if (this.animateCaptionByOpacity)
                this.captionStoryboardHide.begin();
            else
                this.captionPaneSlideOut();

        }
    },

    captionPaneSlideOut: function()
    {
        if (this.captionBackground.height <= 0) { return; }

        /// <summary>Slides the control out of view.</summary>
        var start = this.slideTransform.y;
        var finish = 0;
        var distance = this.captionBackground.height;
        var duration = (start - finish) / distance; //this.options.slideAnimationDuration;

        if (duration > 0)
        {
            this.slideKeyFrame1.value = start;
            this.slideKeyFrame2.value = finish;
            this.slideKeyFrame2.keyTime = "0:0:" + duration.toFixed(8);
            this.slideStoryboard.begin();
        }
    },

    captionPaneAction_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (!this.captionVisible)
        {
            return;
        }
        if (!this.captionAutoHide)
        {
            this.alwaysOnTopCaption.text = "Schovávat"
            this.captionAutoHide = true;
            this.alwaysOnTopPaneShow.begin();
        }
        else
        {
            this.alwaysOnTopCaption.text = "Neschovávat";
            this.captionAutoHide = false;
            this.alwaysOnTopPaneShow.begin();
        }
    },

    controlPane_MouseEnter: function(sender, eventArgs)
    {
        this.controlPaneShow.begin();
    },

    controlPane_MouseLeave: function(sender, eventArgs)
    {
        if (this.controlAutoHide)
            this.controlPaneHide.begin();
    },

    controlBackground_MouseLeftButtonDown: function(sender, eventArgs)
    {
        if (!this.controlAutoHide)
        {
            this.alwaysOnTopControlCaption.text = "Schovávat"
            this.controlAutoHide = true;
            this.alwaysOnTopControlPaneShow.begin();
        }
        else
        {
            this.alwaysOnTopControlCaption.text = "Neschovávat";
            this.controlAutoHide = false;
            this.alwaysOnTopControlPaneShow.begin();
        }
    },

    nextImagePane_MouseEnter: function(sender, eventArgs)
    {
        this.nextImageStoryboardShow.begin();
    },

    nextImagePane_MouseLeave: function(sender, eventArgs)
    {
        this.nextImageStoryboardHide.begin();
    },

    prevImagePane_MouseEnter: function(sender, eventArgs)
    {
        this.prevImageStoryboardShow.begin();
    },

    prevImagePane_MouseLeave: function(sender, eventArgs)
    {
        this.prevImageStoryboardHide.begin();
    },

    getTotalSlides: function()
    {
        return this.slideSettings.total;
    },

    button_MouseEnter: function(sender, eventArgs)
    {
        sender.opacity = 1;
    },

    button_MouseLeave: function(sender, eventArgs)
    {
        sender.opacity = 0.5;
    }
}

