﻿/// <reference name="MicrosoftAjax.js"/>
var PhotoStream = Class.create({
    initialize: function(name, streamer, container) {
        //Ref parent streamer
        this.photoStreamer = streamer;

        //Create queues
        this.name = name;
        this.displayIndex = 0;
        this.downloadQueue = new Array();

        //Create wrapper div
        var div = new Element('div');
        this.wrapper = div;
        div.className = 'photoStream';
        container.appendChild(div);
    },

    downloadPhoto: function(hiname, loname, title, metadata, googleUri) {
        var idx = this.downloadQueue.length;
        var img = new Element('img');
        var item = { element: img, filenameHi: hiname, filenameLo: loname, title: title, metadata: metadata, order: idx, googleUri: googleUri };
        this.downloadQueue[idx] = item;

        this.wrapper.appendChild(img);
        img.alt = item.title;
        img.photoStream = this;
        img.photoStreamProps = item;
        img.hide();
        Event.observe(img, 'load', this.onLoadThumb);
        Event.observe(img, 'click', this.onClickThumb);
        img.src = item.filenameLo;
    },

    onLoadThumb: function(evt) {
        this.photoStream.displayThumb(this.photoStreamProps.order);
    },

    displayThumb: function(idx) {
        //Ready to render next item? (i.e. is it downloaded?)
        if (this.displayIndex != idx) return;
        //Are we at the end of our displaylist?
        if (idx >= this.downloadQueue.length) {
            this.photoStreamer.fetchPhotos();
            return;
        }

        var item = this.downloadQueue[idx];
        this.displayIndex++;

        //Resize the divs so the image show side by side
        var img = item.element;
        Event.observe(img, 'load', this.onLoadThumb);
        var div = img.parentNode;
        var width = (Element.getWidth(div) + Element.getWidth(img)) + 1;
        div.style.width = width + 'px';
        if (Element.getWidth(div.parentNode) < width)
            div.parentNode.style.width = div.style.width;
        if (Element.getWidth(document._photoStreamer.transparentDiv) < width) {
            document._photoStreamer.transparentDiv.style.width = div.style.width;
//            if (width < 1000)
//                $('copyright').style.left = '900px';
//            else
//                $('copyright').style.left = (width - 100) + 'px';
        }


        //Fade in
        new Effect.Appear(img, { afterFinish: function() { img.photoStream.displayThumb(idx + 1); }, duration: 0.4 + (Math.random() * 1), queue: { position: 'end', scope: this.name} });
    },

    onClickThumb: function(evt) {
        this.photoStream.photoStreamer.zoomPhoto(this, this.photoStreamProps.metadata, this.photoStreamProps.filenameHi, this.photoStreamProps.googleUri);
    }
});

var PhotoStreamer = Class.create({
    initialize: function(divContainer, divCount, transparent, zoom, deets, load) {
        document._photoStreamer = this;

        this.queueStream = 0;
        this.streams = new Array();
        for (var i = 0; i < divCount; i++)
            this.streams[i] = new PhotoStream('stream' + i, this, divContainer);

        this.loadingDiv = load;
        this.transparentDiv = transparent;
        this.zoomDiv = zoom;
        this.detailsDiv = deets;
        this.fetchStart = 30;
        this.autoShowPhoto = null;

        transparent.hide();
        zoom.hide();
        deets.hide();
        load.hide();

        Event.observe(this.transparentDiv, 'click', this.onZoomImageClick);

        //Check if a particular image should be loaded
        var href = window.location.href;
        var idx = href.indexOf('#');
        if (idx > 0) {
            var photo = href.substring(idx + 1, href.length);
            this.autoShowPhoto = photo;
        }
    },
    addPhoto: function(fileName, title, camera, lens, exposure, date) {
        //Get the next stream
        var idx = this.queueStream++;
        var stream = this.streams[idx];
        if (this.queueStream >= this.streams.length) this.queueStream = 0;

        //Queue the photo for download
        var deets = '';
        if (!title) title = '(Untitled)';
        deets += '<b>' + title + '</b><br/>';
        if (date) deets += 'Date: ' + date + '<br/>';
        if (exposure) deets += 'Exposure: ' + exposure + '<br/>';
        if (lens) deets += 'Lens focal length: ' + lens + '<br/>';
        if (camera) deets += 'Camera: ' + camera + '<br/>';

        stream.downloadPhoto('http://www.andyvermeulen.com/photos/' + fileName, 'http://fs' + (idx + 1) + '.andyvermeulen.com/thumbs/' + fileName, title, deets, '/#' + fileName);

        //Auto show it if needed
        if (this.autoShowPhoto == fileName)
            setTimeout(new function() { document._photoStreamer.zoomPhoto(null, deets, 'http://www.andyvermeulen.com/photos/' + fileName, 'http://www.andyvermeulen.com/#' + fileName); }, 1000);
    },
    zoomPhoto: function(img, metadata, filename, googleUri) {
        var ps = document._photoStreamer;
        new Effect.toggle(ps.transparentDiv, 'appear', { from: 0, to: .4, duration: .4 });
        new Effect.toggle(ps.loadingDiv, 'appear', { from: 0, to: 1, duration: .4 });

        ps.detailsDiv.update(metadata);
        if (img)
            ps.zoomDiv.style.left = (Element.cumulativeOffset(img).left - Element.viewportOffset(img).left + 100) + 'px';
        else
            ps.zoomDiv.style.left = '100px';
        ps.loadingDiv.style.left = ps.zoomDiv.style.left;

        var zoomImg = new Element('img');
        Event.observe(zoomImg, 'load', ps.onZoomImageLoad);
        Event.observe(zoomImg, 'click', ps.onZoomImageClick);
        ps.zoomDiv.update(zoomImg);
        zoomImg.src = filename;

        //Google track the view
        window.location.href = googleUri;
        try { pageTracker._trackPageview(googleUri); } catch (ex) { }
    },
    onZoomImageLoad: function(evt) {
        var ps = document._photoStreamer;

        var left = parseInt(ps.zoomDiv.style.left);
        ps.detailsDiv.style.left = (Element.getWidth(ps.zoomDiv) + left) + 'px';
        new Effect.toggle(ps.zoomDiv, 'appear', { from: 0, to: 1, duration: .6, queue: { scope: 'zoom'} });
        new Effect.toggle(ps.detailsDiv, 'appear', { from: 0, to: 1, duration: .6, queue: { scope: 'zoom'} });
    },
    onZoomImageClick: function(evt) {
        var ps = document._photoStreamer;

        var queue = Effect.Queues.get('zoom');
        queue.each(function(effect) { effect.cancel(); });

        //window.location.href = 'http://www.andyvermeulen.com/';

        new Effect.toggle(ps.loadingDiv, 'appear', { from: 1, to: 0, duration: .2, queue: { scope: 'zoom'} });
        new Effect.toggle(ps.transparentDiv, 'appear', { from: .4, to: 0, duration: .2, queue: { scope: 'zoom'} });
        new Effect.toggle(ps.zoomDiv, 'appear', { from: 1, to: 0, duration: .6, queue: { scope: 'zoom'} });
        new Effect.toggle(ps.detailsDiv, 'appear', { from: 1, to: 0, duration: .6, queue: { scope: 'zoom'} });
    },
    fetchPhotos: function() {
        if (this.fetchStart <= 0 || this.fetching) return;
        this.fetching = true;

        com.andyvermeulen.web.Ajax.GetPhotos(this.fetchStart, 20, this.fetchPhotosSuccess, null, null);
        this.fetchStart += 20;
    },
    fetchPhotosSuccess: function(ajaxPhotos, userContext, methodName) {
        var ps = document._photoStreamer;
        ps.fetchStart += 20;

        ps.fetching = false;
        
        for (var i = 0; i < ajaxPhotos.length; i++) {
            var p = ajaxPhotos[i];
            ps.addPhoto(p.Filename, p.Title, p.Camera, p.Lens, p.Exposure, p.Date);
        }
        if (ajaxPhotos.length < 20)
            ps.fetchStart = -1;

        //setTimeout(function() { document._photoStream.renderPhoto() }, 0);
    }
});
