GalleryData = {

    SERVICES: {
        studies: '_WebServices/ContentService.svc/GetCaseStudy',
        people: '_WebServices/ContentService.svc/GetPerson'
    },
    
    ERRORMSG: '<p class="msg"><strong>Oops</strong> there appears to have been an error!</p>',
    
    LDR: '<span id="ldr">Loading...</span>',
    
    service: null,

    cache: [],
    
    callback: null,
    request: null,
    
    
    init: function(type) {
        this.service = pathToRoot+this.SERVICES[type];
        this.createXhrObject();
    },
    
    
    createXhrObject: function () {
	    $.ajaxSetup({
		    type: "GET",
		    url: this.service,
		    contentType: "application/x-www-form-urlencoded",
		    dataType: "json",
		    success: function(){
			    return GalleryData.handleResponse.apply(GalleryData, arguments);
		    },
		    error: function(){
			    return GalleryData.handleResponse.apply(GalleryData, arguments);
		    },
		    beforeSend: function() {
		        return GalleryData.createLoader();
		    }
	    });
    },
    
    
    createLoader: function() {
        var ldr = $('#ldr');
        if (ldr.length === 0) {
            ldr = $('#box').append(this.LDR);
        }
        return ldr;
    },
    
    
    deleteLoader: function() {
        return $('#ldr').remove();
    },
    
    
    addToCache: function(indx, response) {
        return this.cache['_'+indx] = response;
    },
    
    
    getData: function(callback, request) {
        this.callback = callback;
        this.request = request;
        if (this.cache['_'+request]) {
            callback.success.call(
		        callback.scope, '', this.cache['_'+request], callback.args);    
        } else {
            this.makeConnection();    
        };
    },
    
    
    makeConnection: function () {
        // data: {id: this.request, isLive: isLive.toString()},
	    return $.ajax({data: {
	        id: this.request, isLive: isLive.toString()}});
    },
    
    
    handleResponse: function (response, status) {
	    if (status !== 'error') {
		    this.addToCache('_'+this.request, response);
		    this.callback.success.call(
		        this.callback.scope, this.request, response, this.callback.args);
	    } 
	    else {
	        var o = {
	            Media: null,
	            Status: status,
	            Html: [this.ERRORMSG]
            };
		    this.callback.success.call(
		        this.callback.scope, this.request, o, this.callback.args);
	    }
	    return;
    }
    

};


Gallery = {


    CONTAINER: 'col2',

    BODYHTML: '<div class="figure" style="height: 422px;">\
            </div><div class="caption clear"></div>',

    BOXHTML: '<div class="box" id="box">\
                <div class="header clear"><a href="#">close</a></div>\
                <div class="caption clear"></div>\
            </div>',

    csid: null,

    box: {},

    content: [],

    init: function() {
        var dims = this.getHeight();
        return $.extend(this.box, {
            element: this.render(),
            start: {},
            finish: { height: dims.height, width: dims.width }
        });
    },
    
    getHeight: function() {
        return $.browser.msie ? 
            {height: 555, width: 606} :
            {height: 553, width: 604};
    },

    render: function() {
        return $(this.BOXHTML).appendTo('#' + this.CONTAINER);
    },


    update: function(o) {
        $.extend(this.box.start,
            this.getElementDims(o.element));
        this.csid = o.id;
        this.empty();
        this.animate();
    },


    empty: function() {
        this.content = [];
        $('.asset', this.box.element).remove();
    },


    getCaseStudy: function() {
        return GalleryData.getData({
            success: this.setCaseStudy, scope: this, args: ''
        }, this.csid);
    },


    setCaseStudy: function(request, response, args) {
        this.content = response.Html;
        if (response.Media === 'Image') {
            this.getImage(response, this.addContent);
        }
        else if (response.Media === 'Flash') {
            this.getSwf(response, this.addContent);
        }
        else if (response.Media === null && response.Status === 'error') {
            this.addContent();
        };
    },


    getImage: function(response, callback) {
        if (arguments.length === 2) {
            var i = new Image();
            var self = this;
            i.onload = function() {
                self.content.unshift('<div class="figure"><img src="' + response.Url +
                    '" width="' + i.width + '" height="' + i.height + '" /></div>');
                return self.getImage.call(self, response, callback, i);
            };
            i.src = response.Url;
        } else {
            callback.apply(this, arguments);
        };
    },


    getSwf: function(response, callback) {
        this.content.unshift(
            '<div id="flp">\
            <object type="application/x-shockwave-flash"\
                data="' + response.Url + '"\
                    width="604" height="422">\
                <param name="movie"\
                    value="' + response.Url + '" />\
                <param name="wmode"\
                    value="transparent" />\
            </object></div>');
        callback.apply(this, arguments);
    },


    addContent: function(response) {
        var self = this;
        var elem = this.content.shift();
        GalleryData.deleteLoader();
        if (elem && elem !== '') {
            var target = elem.search(/<div class="figure"|<div id="flp"/g) !== -1 ?
                this.box.element : this.box.element.find('.caption');
            return $(elem)
                .appendTo(target).addClass('asset')
                .hide().fadeIn(300, function() {
                    if (response.Html.length > 0) {
                        self.addContent.call(self, response);
                    } else {
                        self.box.element.children('.header').show();
                        // self.setTabIndex.call(self);
                    };
                });
        } else {
            if (response.Html.length > 0) {
                self.addContent.call(self, response);
            } else {
                self.box.element.children('.header').show();
                // self.setTabIndex.call(self);
            };
        };
    },


    setTabIndex: function() {
        /*
        this.box.element.append('<p><a href="#">link in para</a><p>');
        this.box.element.append('<div><p><a href="#">link in para in a div</a><p></div>');
        this.box.element.append('<span><p><a href="#">link in para in a div</a><p></span>');
        
        $('a', this.box.element).each(function(i) {
        $(this).attr('tabindex', i === 0 ? 1 : -1);
        });
        
        var focused = false;
        var self = this;
        
        $(document).keydown(function(e) {
        if (e.keyCode === 40) {
        $('a', self.box.element).each(function() {
        console.log(typeof this.tabIndex);
        if (this.tabIndex === 1) {
        console.log(this);
        focused = this;
        this.tabIndex = -1;
        this.style.background = 'Red';
        this.focus();
        } 
        if (focused) {
        console.log('focused');
        this.tabIndex = 1;
        return false;
        };    
        });
        };
        });
        */
    },


    animate: function() {
        var self = this;
        this.setFinish();
        this.box.element.children('.header').hide();
        return this.box.element.css($.extend({}, this.box.start, { display: 'block' }))
            .animate($.extend(this.box.finish, { opacity: 1 }), 200, function() {
                self.getCaseStudy.apply(self, arguments);
            });
    },


    hide: function() {
        return this.box.element.hide();
    },


    close: function() {
        var self = this;
        return this.box.element
            .animate($.extend(this.box.start, { opacity: 0.5 }), 200, function() {
                self.hide.apply(self);
            });
    },


    round: function(n) {
        return Math.round(n * 100) / 100;
    },


    setFinish: function() {
        var d = this.getContainerDims();
        if (this.round(this.box.start.left / d[0]) > 0.25) {
            var l = Math.floor(d[0] * 0.25) + 3;
        };
        if (this.box.start.top + this.box.finish.height > d[1]) {
            var t = (this.box.start.top - ((this.box.start.top + this.box.finish.height) - d[1])) - 11;
        };
        return $.extend(this.box.finish, {
            left: l || 0, top: t != undefined ? t < 0 ? 0 : t : this.box.start.top
        });
    },


    getElementDims: function(elem) {
        var el = $(elem);
        return $.extend({}, el.position(), {
            width: el.outerWidth(), height: el.outerHeight()
        });
    },


    getContainerDims: function() {
        return [
            $('#' + this.CONTAINER).outerWidth(),
            $('#' + this.CONTAINER).outerHeight()
        ];
    }

};



GLTrigger = $.klass({

    callback: null,
    scope: null,

    initialize: function(fn, scope) {
        this.callback = fn;
        this.scope = scope;

    },
    
    
    update: function(id, el) {
        this.callback.call(this.scope, {id: id, element: el});
    },
   
    
    onclick: function(e) {
        var div = e.target.className.indexOf('box') != -1 ?
            $(e.target) : $(e.target).closest('.box');
        this.update(div.attr('class').match(/\d+/).pop(), div.get(0)); 
        return false;
    },
    

    onkeydown: function(e) {
        if (e.keyCode === 32 || e.keyCode === 13) {
            var div = $(e.target).find('.box');
            this.update(div.attr('class').match(/\d+/).pop(), div.get(0));   
            return false;       
        };
    }

});


Box = $.klass({

    initialize: function() {
        this.bind();
    },
    
    bind: function() {
        var close = $('.header a', this.element);
        close.click(function() {
            Gallery.close.call(Gallery);
            return false; 
        });
        close.keydown(function() {
            if (e.keyCode === 32 || e.keyCode === 13) {
                Gallery.close.call(Gallery);    
            };
        });
    }
});

