﻿$(function() {

    var photography = new DS.Photography();
    photography.init();
    
    $("#photography-menu-trigger a").tooltip({
        position: ['bottom', 'center'], 
        offset: [12, 0],
        opacity: 0.8,
        delay: 250,
        api: true
    });
    
    if (DS.siteUnderConstruction)
        $('ul.menu').hide();
});

DS.Photography = CClass.create(
    function() {

        // private
        var defaults = {
            albumTickerSelector: "#ticker",
            photoSelector: "#photo",
            thumbnailsSelector: "#thumbnails",
            thumbsActivatorSelector: "#thumbs-activator",
            navLinksSelector: '#nav-links',
            imageInfoActivatorSelector: "#image-info-activator",
            imageInfoSelector: "#image-info",
            thumbsWidth: 100,
            thumbsSlideDelay: 300,
            defaultImageSrc: DS.Utils.Path.Combine(DS.applicationURL, '/Content/images/SPLASH2.jpg'),
            underConstructionImageSrc: DS.Utils.Path.Combine(DS.applicationURL, '/Content/images/coming-soon.jpg'),
            progressImageSrc: DS.Utils.Path.Combine(DS.applicationURL, '/Content/images/progress2.gif'),
            thumbnailsViewCount: 10,
            imageInfoHeight: 40
        };

        var opts, $photo, $photoImg, $thumbnails, $thumbsActivator, $navLinks, $imageInfoActivator, $albumTicker, $imageInfo, $thumbnailContainer;

        var direction = {
            up: 1,
            down: 2,
            none: 0
        };

        var duration = {
            slow: 1000,
            normal: 500,
            fast: 150,
            none: 0
        };

        var pictures = [],
            albumNames = [],
            lowerIndex = 0,
            higherIndex = 0,
            currentIndex = 0,
            lastLoadedPictureIndex = 0,
            isAlbumLoaded = false,
            containerHeight = 0,
            slideDirection = direction.none,
            slideDuration = duration.none,
            thumbHeight = 85,
            slideHeight = 0;

        function pictureHasImageInfo()
        {
            return pictures[currentIndex].ShortDescription.length > 0 || pictures[currentIndex].LongDescription.length > 0;
        }

        function showThumbnails() {
            if (!isAlbumLoaded)
                return;

            $thumbnails
            .stop()
            .show()
            .animate({
                "width": "+=" + opts.thumbsWidth + "px"
            }, opts.thumbsSlideDelay);

            $thumbsActivator.hide();
            $imageInfoActivator.hide();
        }

        function hideThumbnails() {
            if (!isAlbumLoaded)
                return;

            // stop thumbnails slide container up/down animation
            $thumbnailsContainer.stop();
            slideDirection = direction.none;
            slideDuration = duration.none;

            // stop thumbnails viewer open/close animation            
            $thumbnails
            .stop()
            .animate({ "width": "0%" }, opts.thumbsSlideDelay);

            $thumbsActivator.show();
            
            if (pictureHasImageInfo())
                $imageInfoActivator.show();
        }

        function enableAlbumNavigation() {
            $thumbsActivator.show();
            
            if (pictureHasImageInfo())
                $imageInfoActivator.show();
                
            $navLinks.show();
        }

        function disableAlbumNavigation() {
            $thumbsActivator.hide();
            $imageInfoActivator.hide();
            $navLinks.hide();
        }

        // public
        return {
            init: function(options) {

                var self = this;
                
                // merge user options with defaults
                opts = $.extend(defaults, {}, options);
                ////console.log(defaults, options, opts);

                // initialize jquery elements
                $albumTicker = $(opts.albumTickerSelector);
                $photo = $(opts.photoSelector);
                $thumbnails = $(opts.thumbnailsSelector);
                $thumbnailsContainer = $('.container', $thumbnails);
                $thumbsActivator = $(opts.thumbsActivatorSelector);
                $imageInfoActivator = $(opts.imageInfoActivatorSelector);
                $imageInfo = $(opts.imageInfoSelector);
                $photoImg = $('> img', $photo);
                $navLinks = $(opts.navLinksSelector);

                // set initial image
                if (DS.siteUnderConstruction)
                    $photoImg.attr("src", opts.underConstructionImageSrc);
                else
                {
                    albumProxy.getAlbumNames(function(result) {
                       
                       albumNames = result;
                       
                       var $albums = $("#header .photography-tooltip");
                       $albums.empty();
                       
                       var $list = $('<ul></ul>');
                       $albums.append($list);
                       
                       $.each(albumNames, function(index, item) {
                        
                        var $item = $('<li><a href="#">' + item + '</a></li>');
                        $list.append($item);
                        
                       });
                       
                       $("#header .photography-tooltip a").unbind("click").click(function() {
                            var album = $(this).text();        
                            var api = $("#photography-menu-trigger a").tooltip();
                            api.hide();
                            
                            self.loadAlbum(album);
                        });
                        
                        $("a#tearsheets").unbind("click").click(function() {
                            var album = $(this).text();        
                            self.loadAlbum(album);
                        });
                        
                        $("a#about").unbind("click").click(function() {
                            self.showAboutMe();
                        });
                        
                    });
                    
                    $photoImg.attr("src", opts.defaultImageSrc); 
                }

                disableAlbumNavigation();

                this.bindEvents();
            },

            bindEvents: function() {

                var self = this;

                $thumbsActivator.hover(
                    function() {
                        showThumbnails();
                    },
                    function() { }
                );

                $thumbnails.hover(
                    function() { },
                    function() { hideThumbnails(); }
                );

                $thumbnails.mousemove(function(e) {

                    // mouse Y position relative to outer thumbnails container
                    var y = e.pageY - $(this).offset().top;

                    // outer thumbnails container width
                    var height = 590;

                    // hit test position
                    var hit = height / 3;

                    // height of each thumb
                    var thumbPx = thumbHeight;

                    // number of pixels to animate at a time
                    var slide1 = 5;

                    var thumbsToShowAfterScrollingIsDone = 2;

                    // hit test: mouse is positioned in the lower area to scroll down with normal speed
                    if (y > height - hit) {

                        // hit test: mouse is position in the lower area to scroll down with fast speed
                        if (y > height - 30) {

                            // check if animation for same parameters is already in progress
                            // if it is, let it be...
                            if (slideDirection == direction.down && slideDuration == duration.fast)
                                return;

                            // set parameters: scrolling down with fast duration
                            slideDirection = direction.down;
                            slideDuration = duration.fast;
                        }
                        else {

                            // check if animation for same parameters is already in progress
                            // if it is, let it be...
                            if (slideDirection == direction.down && slideDuration == duration.normal)
                                return;

                            // set parameters: scrolling down with fast duration
                            slideDirection = direction.down;
                            slideDuration = duration.normal;
                        }

                        // get current top value for thumbnails container
                        var topPx = $thumbnailsContainer.css("top");
                        if (topPx.endsWith("px"))
                            topPx = topPx.left(topPx.length - 2)

                        topPx = parseFloat(topPx);
                        if (isNaN(topPx))
                            topPx = 0;

                        // get number of pixels to scroll down
                        var pxToMove = Math.abs(topPx)

                        // adjust number of pixels to move: if current position is 0, then we are at the top, and we have to move all the way, use the entire height
                        if (pxToMove == 0) {
                            pxToMove = slideHeight - thumbPx * thumbsToShowAfterScrollingIsDone;
                        }

                        // adjust number of pixels to move: if current number of pixels is over allowed height, force it to 0 to make sure we are not moving
                        else if (pxToMove > slideHeight) {
                            pxToMove = 0;
                            return;
                        }

                        // adjust number of pixels to move: scroll based on height minues what has already been scrolled minus number of thumbs to show after scrolling is done
                        else {
                            pxToMove = slideHeight - pxToMove - (thumbPx * thumbsToShowAfterScrollingIsDone);
                        }

                        // calculate duration parameter
                        var picsToMove = pxToMove / thumbPx;
                        if (picsToMove == 0)
                            picsToMove = 1;

                        var ms = picsToMove * slideDuration;

                        //console.log("Px=", topPx, "PxToMove=", pxToMove, "PicsToMove=", picsToMove, "Duration=", ms);

                        // and finally animate...
                        $thumbnailsContainer
                            .stop()
                            .animate({
                                top: "-=" + pxToMove + "px"
                            }, ms);
                    }

                    // hit test: mouse is positioned in the upper area to scroll up with normal speed
                    else if (y < hit) {

                        // hit test: mouse is positioned in the upper area to scroll up with fast speed
                        if (y < 30) {

                            // check if animation for same parameters is already in progress
                            // if it is, let it be...
                            if (slideDirection == direction.up && slideDuration == duration.fast)
                                return;

                            // set parameters: scrolling up with fast duration
                            slideDirection = direction.up;
                            slideDuration = duration.fast;
                        }
                        else {
                            // check if animation for same parameters is already in progress
                            // if it is, let it be...
                            if (slideDirection == direction.up && slideDuration == duration.normal)
                                return;

                            // set parameters: scrolling up with fast duration
                            slideDirection = direction.up;
                            slideDuration = duration.normal;
                        }

                        // get current top value for thumbnails container
                        var topPx = $thumbnailsContainer.css("top");
                        if (topPx.endsWith("px"))
                            topPx = topPx.left(topPx.length - 2)

                        topPx = parseFloat(topPx);
                        if (isNaN(topPx))
                            topPx = 0;

                        // stop animation if current top value is greater than 0, it should be 0 or less when scrolling up
                        if (topPx > 0) {

                            $thumbnailsContainer
                            .stop()
                            .css("top", 0);

                            return;
                        }

                        // get number of pixels to scroll
                        var pxToMove = Math.abs(topPx);

                        var picsToMove = pxToMove / thumbPx;
                        var ms = picsToMove * slideDuration;

                        //console.log("Px=", topPx, "PxToMove=", pxToMove, "PicsToMove=", picsToMove, "Duration=", ms);

                        $thumbnailsContainer
                            .stop()
                            .animate({
                                top: "+=" + pxToMove + "px"
                            }, ms, function() {
                                $(this)
                                .stop()
                                .css("top", 0);
                            });
                    }

                    // hit test: mouse is positioned in the middle area with no scrolling enabled, stop any current animation
                    else {
                        $thumbnailsContainer.stop();
                        slideDirection = direction.none;
                        slideDuration = duration.none;
                    }
                });

                $photo.hover(
                    function() { hideThumbnails(); },
                    function() { }
                );

                $imageInfoActivator.hover(
                    function() {

                        if ($imageInfo.height() < opts.imageInfoHeight) {
                            $imageInfo.css({
                                "height": opts.imageInfoHeight,
                                "padding": "15px 30px"
                            });
                        }

                        $imageInfo
                            .stop()
                            .slideDown();
                    },
                    function() {
                        $imageInfo
                            .stop()
                            .slideUp();
                    }
                );

                $photo.click(
                    function() {
                        if (currentIndex + 1 >= pictures.length)
                            currentIndex = -1; // start over
                            
                        self.showPhoto(++currentIndex);

                        $('.thumb', $thumbnailsContainer)
                        .removeClass("current")
                        .filter(":eq(" + currentIndex + ")").addClass("current");
                    }
                );
            },

            loadAlbum: function(albumName) {
                //console.log(">>> loadAlbum");                

                containerHeight = $photo.offsetParent().height();

                var self = this,
                    message = "Loading " + albumName + "...";

                $photo.empty();
                $thumbnailsContainer.empty();

                //console.log("Photo Container Height:", containerHeight);
                var $loading = $('div#splash > div.loading')
                    .clone()
                    .appendTo($photo)
                    .find('span')
                    .html(message)
                    .end()
                    .find('img')
                    .attr('src', opts.progressImageSrc)
                    .end()
                    .css("margin-top", containerHeight / 2 - 10)
                    .show();

                //$progress.clone().appendTo($photo).find("span").html(message);

                pictures = [];
                lowerIndex = 0;
                upperIndex = 0;
                lastLoadedPictureIndex = 0;

                //console.log(message);

                albumProxy.loadAlbum(albumName, function(result) {

                    $("#header .ticker span").html(albumName);

                    if (result.Pictures.length == 0) {

                        self.showPhoto(opts.underConstructionImageSrc)
                        disableAlbumNavigation();

                        isAlbumLoaded = false;
                    }
                    else {

                        pictures = result.Pictures;
                        currentIndex = 0;
                        isAlbumLoaded = true;

                        self.showPhoto(currentIndex)
                        self.loadThumbnails(0);

                        enableAlbumNavigation();
                    }

                    //console.log("Number of pictures loaded: " + pictures.length);
                });

                //console.log("<<< loadAlbum");
            },

            showPhoto: function(arg, callback) {
                var url = arg;
                var picture = null;

                if (typeof arg == "number") {

                    if (arg > pictures.length - 1)
                        return;

                    currentIndex = arg;
                    picture = pictures[arg];
                    url = picture.FullUrl;
                    url = DS.Utils.Path.Combine(DS.applicationURL, url);
                }

                var $img = $('<img></img>')
                    .load(function() {
                        $photo.empty();
                        $photo.append($(this));
                        $(this).fadeIn();

                        if (picture != null) {
                            if (!pictureHasImageInfo()) {
                                $imageInfoActivator.hide();
                            }
                            else {
                                $imageInfo.empty();

                                // get width of the image to position image-info over it                                
                                var $img = $(this);
                                var size = ($photo.width() - $img.width()) / 2;
                                size = size + 15 + "px";

                                // add picture info
                                var shortInfo = $('<span class="short"></span>').html(picture.ShortDescription);
                                var longInfo = $('<span class="long"></span>').html(picture.LongDescription);
                                $imageInfo
                                    .append(shortInfo)
                                    .append(longInfo)
                                    .css({
                                        'width': $img.width() - 30,
                                        'left': 0,
                                        'paddingLeft': 30,
                                        'paddingRight': 30,
                                        'paddingTop': 15,
                                        'paddingBottom': 15
                                    })
                                    .appendTo($photo);

                                $imageInfoActivator.show();
                            }

                            $(".info", $navLinks).html("" + (currentIndex + 1) + " of " + pictures.length);                            
                        }
                        
                        if (callback != 'undefined' && callback != null)
                            callback();
                    })
                    .css("display", "none")
                    .attr('src', url);
            },

            loadThumbnails: function() {

                var self = this;

                //console.log("Loading thumbnails...");
                //var upperIndex = startIndex + opts.thumbnailsViewCount - 1;

                var j = 0;
                for (var i = 0; i < pictures.length; i++) {

                    var $thumb = $('<div class="thumb"></div>');
                    var url = DS.Utils.Path.Combine(DS.applicationURL, pictures[i].ThumbUrl);
                    var $img = $('<img></img>')
                        .attr('src', url)
                        .css('position', 'relative');

                    ////console.log("Adding image: ", url);

                    $thumb[0].absoluteIndex = i;
                    $thumb[0].relativeIndex = j++;
                    $thumb.append($img).appendTo($thumbnailsContainer);

                    if (i == 0)
                        $thumb.addClass("current");
                }

                slideHeight = pictures.length * 85;
                
                $thumbnailsContainer
                    .css({
                        "height": slideHeight,
                        "top": 0
                    });
                            
                //console.log("Container Height: ", slideHeight);

                var $thumbs = $('div.thumb', $thumbnailsContainer)
                .bind("mouseenter mouseleave", function() {
                    
                    // TOD: do not use hover effect in IE for now since it causes flickering, but gotta find a working solution for this!
//                    if($.browser.msie)
//                        return;
                        
                    $(this).toggleClass("hilite");
                    
                })
                .click(function() {
                    self.showPhoto($(this)[0].absoluteIndex);

                    $thumbs.removeClass("current");
                    $(this).addClass("current");
                });
            },
            
            showAboutMe: function() {
                
                $("#header .ticker span").html("Contact");
                disableAlbumNavigation();
                $photo.empty();
                this.showPhoto(DS.Utils.Path.Combine(DS.applicationURL, '/Content/images/Contact-Page.jpg'), function() {
                    console.log('adding social icons...');
                    $photo.append('\
                    <div style="position: absolute; top: 10px; right: 10px;">\
                        <a href="http://www.facebook.com/dianasonis" title="Friend Me!"><img src="' + DS.Utils.Path.Combine(DS.applicationURL, 'Content/images/FaceBook-icon-32.png') + '"></a>\
                        <a href="http://www.twitter.com/dianasonis" title="Twitter It!"><img src="' + DS.Utils.Path.Combine(DS.applicationURL, 'Content/images/Twitter-icon-32.png') + '"></a>\
                    </div>');
                });
                
                isAlbumLoaded = false;
            }
        };
    });

var albumProxy =
{
    loadAlbum: function(albumName, callback) {
        $.getJSON(DS.Utils.Path.Combine(DS.applicationURL, "/Photography/Albums/") + albumName, callback);
    },
    
    getAlbumNames: function(callback) {
        $.getJSON(DS.Utils.Path.Combine(DS.applicationURL, "/Photography/GetAlbumNames"), callback);
    }
    
};

var homeProxy =
{
    loadAboutMe: function(callback) {
        $.get(DS.Utils.Path.Combine(DS.applicationURL, "/Home/About"), callback);
    }
    
};