var VideoSlideshow = Class.create();
VideoSlideshow.prototype = {

    SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,

    playing: false,

	initialize : function(element, o)
    {
        element = $(element);
        VideoSlideshows.register(element, this);

        this.options = Object.extend({ 
          element:     element,
          thumbnails:  null, 
          tag:         'li',       // assumes li children, override with tag: 'tagname'
          delay:       40,
          selectclass: null,
          format:      this.SERIALIZE_RULE,
          onChange:    Prototype.emptyFunction
        }, arguments[1] || {});

        this.timeout = null;

        children = this.findElements(this.options.thumbnails, this.options);
        this.children = children;
        this.childrenElements = [];

        if (children.length > 0)
        {
            i = 0;
            children.each(function (el) {
                this.childrenElements[i] = new SlideElement(el, this, i);
                i++;
            }.bind(this));

            this.currentChildIndex = 0;
            this.childrenElements[this.currentChildIndex].select();

            this.timeout = setTimeout(this.nextSlide.bind(this), this.options.delay * 1000);
        }
        try {
            this.options.element.addModelListener('STATE', 'slideStateChange');
        } catch (e) {}
    },
    playItemIndex : function(index)
    {
        // this.forceplay = true;
        this.loadItemIndex(index, true);
        /* 
        setTimeout(function() {
            this.options.element.sendEvent('PLAY', 'true');
        }.bind(this), 500);
        */
    },
    loadItemIndex : function (index, _autoStart)
    {
        if (_autoStart == false)
            _autoStart = 'false';
        else
            _autoStart = 'true';

        oldChild = this.childrenElements[this.currentChildIndex];
        oldChild.deselect();

        index = index % this.children.length;
        currentChild = this.childrenElements[index];
        currentChild.select();

        this.currentChildIndex = index;

        try {
            var obj = {file:currentChild.getVideoPath(), image:currentChild.getThumbnailPath()};
            this.options.element.sendEvent('LOAD', obj);
        } catch (e) {
            try {
                var obj = {
                    file:currentChild.getVideoPath(), 
                    image:currentChild.getThumbnailPath(), 
                    autoStart:_autoStart,
                    viewsParameter: currentChild.getViewsParameter(),
                    tags: currentChild.getTags()
                };
                // alert(this.options.element);
                this.options.element.loadFile(obj);
            } catch (e) {
                // alert ('Error ! ' + Object.inspect($H(e)));
            }
        }

        this.options.onChange(currentChild, oldChild);
    },
    nextSlide : function()
    {
        // document.title += '->'; 
        this.loadItemIndex(this.currentChildIndex + 1, false);
        this.timeout = setTimeout(this.nextSlide.bind(this), this.options.delay * 1000);
    },
    stateChange: function (newstate, oldstate)
    {
        if (newstate == 'PLAYING')
        {
            clearTimeout(this.timeout);
        }
        if ((newstate == 'IDLE') || (newstate == 'COMPLETED') || (newstate == 'STOPPED'))
        {
            //document.title += 'stopped!'; 
            // this.playing = false;
            this.timeout = setTimeout(this.nextSlide.bind(this), this.options.delay * 1000);
        }
    },
    findElements: function(element, options) 
    {
        return element.descendants().findAll(function(element) {
            return element.tagName.toLowerCase() == options.tag.toLowerCase();
        });
    }
}

VideoSlideshows = {
    slideshows: [],
    register: function(element, slideShow)
    {
        this.slideshows[$(element).id] = slideShow;
    },
    get: function(element)
    {
        return this.slideshows[$(element).id];
    }
}

function slideStateChange(e)
{
    VideoSlideshowObject = VideoSlideshows.get(e.id);
    VideoSlideshowObject.stateChange(e.newstate, e.oldstate)
}

var SlideElement = Class.create();
SlideElement.prototype = {
    initialize: function (element, parent, index) 
    {
        this.vizualizari = 0;
        this.index = index;
        this.parent = parent;

        desc = element.descendants();

        this.thumbnail = desc.find(this._isThumbnail);
        this.link = desc.find(this._isLink);

        hiddens = desc.findAll(this._isHidden);
        this.thumbnailPath = hiddens[0].value;
        this.videoPath = hiddens[1].value;
        this.viewURL = hiddens[2].value;
        this.treeworksViewsParameter = hiddens[2].value;
        this.vizualizari = hiddens[3].value;
        this.tags = hiddens[4].value;

        this.element = element;

        this.element.onclick = this.slideElementClick.bind(this);
    },
    _isHidden: function(element)
    {
        return (element.tagName.toLowerCase() == 'input') && (element.type.toLowerCase() == 'hidden')  
    },
    _isThumbnail: function(element)
    {
        return element.tagName.toLowerCase() == 'img';
    },
    _isLink: function(element)
    {
        return element.tagName.toLowerCase() == 'a';
    },
    getViewsParameter: function()
    {
        return this.treeworksViewsParameter;
    },
    getVideoPath: function()
    {
        return this.videoPath;
    },
    getThumbnailPath: function()
    {
        return this.thumbnailPath;
    },
    getTitle: function()
    {
        return this.thumbnail.title;
    },
    getHref: function()
    {
        a = this.link;
        if (a)
            return a.href;
        else
            throw new Exception('Elementul slide show-ului nu contine nici un link!');
    },
    getTags: function()
    {
        return this.tags;
    },
    getViewURL: function()
    {
        return this.viewURL;
    },
    getVizualizari: function()
    {
        return this.vizualizari;
    },    
    deselect: function()
    {
        // Element.findChildren(this.element, false, true, 'img')[0].removeClassName('selected');
        Element.removeClassName(this.thumbnail, 'selected');
    },
    select: function()
    {
        Element.addClassName(this.thumbnail, 'selected');
    },
    slideElementClick: function()
    {
        this.parent.playing = true;
        this.parent.playItemIndex(this.index);

        // Don't go to the URL.
        return false;
    }
}
