﻿/// <reference path="jquery-1.3.2-vsdoc2.js" />


(function($) {
    $.extend({
        _wingooliPhotoGallery: {
            galleries: new Array(),
            findGallery: function(id) {
                for (var i = 0, l = this.galleries.length; i < l; i++) {
                    var g = this.galleries[i];
                    if (g.id == id)
                        return g;
                }
                return null;
            },
            config: {
                attr_id: "homam:id",
                attr_galleryId: "homam:galleryId",
                attr_groupId: "homam:groupId"
            }
        }
    });
    $._wingooliPhotoGallery.gallery = function() { };
    $._wingooliPhotoGallery.gallery.prototype = {
        _findFirstGroupOfThisImage: function(id) {
            for (var i = 0, l = this.groups.length; i < l; i++) {
                var g = this.groups[i];
                if (g.findPhoto(id))
                    return g;
            }
            return null;
        },
        findGroup: function(id) {
            for (var i = 0, l = this.groups.length; i < l; i++) {
                var g = this.groups[i];
                if (g.id == id) return g;
            }
            return null;
        },
        selectPhoto: function(pic, group) {
            /// <summary> set gallery.selectedGroup and calls a method in the group to select the photo.
            /// calls group.selectPhoto(pic : photo, big : jqery, caption : jquery)
            /// </summary>
            /// <param name='groupId'>optional, the function tries to find the first group of the image if it is missing</param>            
            if (group == null)
                group = this._findFirstGroupOfThisImage(id);
            this.selectedGroup = group;
            group.selectPhoto(pic, this.big, this.caption);
        },
        selectPhotoById: function(id, groupId) {
            /// <summary>finds the photo and the group associated with the given ids then calls a method to select them.
            /// calls: gallery.selectPhoto(photo, group)
            /// </summary>
            /// <param name='groupId'>optional, the function tries to find the first group of the image if it is missing</param>
            var group = null;
            if (!groupId) {
                group = this._findFirstGroupOfThisImage(id);
            } else
                group = this.findGroup(groupId);
            group.build();
            var photo = null;
            for (var i = 0, l = this.pics.length; i < l; i++) {
                p = this.pics[i];
                if (p.id == id) {
                    photo = p;
                    break;
                }
            }
            if (this.selectedGroup && this.selectedGroup.id != group.id) {
                // group changed
            }
            this.selectedGroup = group;
            this.selectPhoto(photo, group);
        }
    };
    $._wingooliPhotoGallery.group = function() { };
    $._wingooliPhotoGallery.group.prototype = {
        _makePhoto: function(tphoto) {
            /// <sumamry>take a jquery element, creates a photo object, does the ui tricks and returns the photo</summary>
            /// <returns>the newly created photo object</returns>            
            var p = this.gallery.options.makePhoto(tphoto);
            var film = p.filmJq;
            film.attr($._wingooliPhotoGallery.config.attr_galleryId, this.galleryId);
            film.attr($._wingooliPhotoGallery.config.attr_groupId, this.id);
            film.attr($._wingooliPhotoGallery.config.attr_id, p.id);
            film.html("");
            film.click(function() {
                var tp = $(this);
                var gallery = $._wingooliPhotoGallery.findGallery(tp.attr($._wingooliPhotoGallery.config.attr_galleryId));
                gallery.selectPhotoById(tp.attr($._wingooliPhotoGallery.config.attr_id), tp.attr($._wingooliPhotoGallery.config.attr_groupId));
                return false;
            });
            return p;
        },
        addPhoto: function(tphoto) {
            /// <summary>takes a jquery element, create a photo object, does the ui tricks and store the photo object in group.pics array.</summary>
            /// <returns>the newly created photo object</returns>
            var p = this._makePhoto(tphoto);
            this.pics.push(p);
            return p;
        },
        findPhoto: function(id) {
            /// <returns>a photo object if found otherwise null.</returns>
            for (var i = 0, l = this.pics.length; i < l; i++) {
                var p = this.pics[i];
                if (p.id == id)
                    return p;
            }
            return null;
        },
        build: function() {
            /// <summary>this method is intended to be called everytime gallery.selectedGroup changes.</summary>
            if (this.built) return;
            for (var i = 0, l = this.pics.length; i < l; i++) {
                var pic = this.pics[i];
                var filmJq = pic.filmJq;
                var imgJq = pic.thJq;
                this.thumbnailWidth = filmJq.width();
                this.gallery.options.deselectEffect(imgJq);
            }
            this.built = true;
        },
        findImageThContainerJq: function(id) {
            for (var i = 0, l = this.pics.length; i < l; i++)
                if (this.pics[i].id == id)
                return this.pics[i].jq;
            return null;
        },
        findImageThJq: function(id) {
            for (var i = 0, l = this.pics.length; i < l; i++)
                if (this.pics[i].id == id)
                return this.pics[i].thJq;
            return null;
        },
        selectPhoto: function(photo, big, caption) {
            this.thumbnailWidth = photo.filmJq.width();
            var imageThJq = photo.thJq;
            this.gallery.options.selectEffect(big, imageThJq, this.selectPhoto, photo, function() {
                big.attr("src", photo.url);
                caption.html(photo.caption);
            });
            if (this.selectedPhoto && this.selectedPhoto.id != photo.id) {
                this.deselectPhoto(this.selectedPhoto);
            }
            this.selectedPhoto = photo;
            var c = photo.jq;

            var _this = this;
            this.gallery.options.center(c, this);
        },
        deselectPhoto: function(photo) {
            this.gallery.options.deselectEffect(photo.thJq);
        },
        scroll: function(s, scrolled) {
            this.gallery.options.scroll(s, this, scrolled);
        }
    };
})(jQuery);
$.fn.wingooliPhotoGallery = function(options) {
    options = $.extend({
        thumbnailsListSelector: ".group-thumbnails-group ul.list",
        makePhoto: function(tphoto) {
            /// <sumamry>makes a photo object from a jquery element</summary>
            /// <returns>a photo object</returns>            
            return { id: tphoto.attr("class"), url: tphoto.find("a").attr("href"), thUrl: tphoto.find("a img").attr("src"), caption: tphoto.find("span.caption").html(), thJq: tphoto.find("a img"), filmJq: tphoto.find("span.caption"), jq: tphoto };
        },
        deselectEffect: function(thumbJq, f) {
            thumbJq.css("opacity", .7);
            if (f)
                f();
        },
        selectEffect: function(big, th, oldPic, newPic, f) {
            var img = new Image();
            var c1 = false, c2 = false;
            var shown = false;
            var show = function() {
                if (c1 && c2) {
                    big.animate({ opacity: 1 }, 'normal', 'linear');
                    if (f)
                        f();
                    shown = true;
                }
            };
            setTimeout(function() {
                if (!shown) {
                    c1 = true; c2 = true;
                    show();
                }
            }, 5000);
            img.src = newPic.url;
            img.onload = function() { c1 = true; show() };
            big.animate({ opacity: .3 }, 'slow', 'linear', function() {
                c2 = true;
                show();
            });
            th.css("opacity", 1);
        },
        center: function(c, group) {
            /// <parameter name='c'>the photo jq (li)</parameter>
            var width = group.gallery.jq.find(".group-thumbnails-group-container").width();
            var center = function() {
                var l = (c.offset().left);
                if (l < 0)
                    group.scroll(1, center);
                if (l > (width - group.thumbnailWidth))
                    group.scroll(-1, center);
            };
            center();
        },
        scroll: function(s, group, scrolled) {
            /// <parameter name='c'>1 or -1, indicating next and back</parameter>
            var gallery = group.gallery;
            var l = parseFloat(group.jq.css("left"));
            if (isNaN(l)) l = 0;
            l += (s * group.thumbnailWidth);
            group.jq.animate({ left: (l + "px") }, 'normal', 'linear', function() { if (scrolled) scrolled(); });
        },
        bigImageSelector: ".bigimage",
        bigImageCaptionSelector: ".caption-container .caption",
        leftArrowSelector: ".group-thumbnails-section .control.left",
        rightArrowSelector: ".group-thumbnails-section .control.right"
    }, options);
    var jPhotoGallery = $._wingooliPhotoGallery;
    this.each(function(e) {
        var tgallery = $(this);
        var galleryId = (function() { var i = tgallery.attr($._wingooliPhotoGallery.config.attr_id); if (!i) i = ("gal" + (Math.random() * 1000).toString()).toString(); return i; })();
        var gallery = new $._wingooliPhotoGallery.gallery();
        gallery.options = options;
        gallery.id = galleryId;
        gallery = $.extend(gallery, {
            pics: new Array(),
            groups: (function() {
                var jgroups = tgallery.find(options.thumbnailsListSelector);
                var arr = new Array();
                jgroups.each(function() {
                    var tgroup = $(this);
                    var groupId = (function() { var i = tgroup.attr($._wingooliPhotoGallery.config.attr_id); return i; })();
                    var group = new $._wingooliPhotoGallery.group();
                    group.galleryId = galleryId;
                    group.gallery = gallery;
                    group.pics = (function() {
                        var arr = new Array();
                        tgroup.find("li").each(function() {
                            var tphoto = $(this);
                            arr.push(group._makePhoto(tphoto));
                        });
                        return arr;
                    })();
                    group = $.extend(group, {
                        id: groupId,
                        jq: tgroup,
                        built: false,
                        selectedPhoto: null
                    });
                    arr.push(group);
                });
                return arr;
            })(),
            pics: new Array(),
            jq: tgallery,
            big: tgallery.find(options.bigImageSelector),
            caption: tgallery.find(options.bigImageCaptionSelector),
            selectedGroup: null
        });
        (function() {
            for (var i = 0, l = gallery.groups.length; i < l; i++) {
                for (var j = 0, lj = gallery.groups[i].pics.length; j < lj; j++) {
                    gallery.pics.push(gallery.groups[i].pics[j]);
                }
            }
        })();
        gallery.jq.find(options.leftArrowSelector).click(function() {
            gallery.selectedGroup.scroll(1);
        });
        gallery.jq.find(options.rightArrowSelector).click(function() {
            gallery.selectedGroup.scroll(-1);
        });
        for (var i = 0; i < gallery.groups.length; i++)
            gallery.groups[i].build();
        jPhotoGallery.galleries.push(gallery);
    });
}


$(document).ready(function() {
    var h = $(".imageGallery");
    h.addClass("wingooli");
    h.wingooliPhotoGallery();
});