jQuery.fn.delay = function(time, func) {
    this.each(function() {
        setTimeout(func, time);
    });

    return this;
};

/**********************************************************************
* FORM HANDLER
*********************************************************************/
var Form = function(form) {
    this.form = $(form);
    this.validators = {
        email: 'Please enter a valid email address',
        required: 'Please enter a '
    };
    this.settings = {
        XHR: false,
        replace: ''
    };
    this.prepare();
}

Form.prototype.prepare = function() {
    this.form.bind('submit', { 'method': 'onSubmit' }, this.closureEvent());
    try {
        var settings = JSON.parse(this.form.attr('title'));
        this.form.attr('title', '');
    } catch (e) {
        var settings = {};
    }
    for (setting in settings) {
        if (this.settings[setting] != 'undefined') {
            this.settings[setting] = settings[setting];
        }
    }
}

Form.prototype.valid = function() {
    var errors = [];
    var fields = this.form.find('input,select,textarea');
    for (var i = 0; i < fields.length; i++) {
        var field = $(fields[i]);
        if (field.attr('type') == 'submit') continue;
        if (!field.attr('validate')) continue;
        var validators = field.attr('validate').split(',');
        for (var j = 0; j < validators.length; j++) {
            var result = this.validate(validators[j], field);
            if (result != true) {
                errors.push(result);
                break;
            }
        }
    }
    if (errors.length > 0) {
        var error = '';
        for (var i = 0; i < errors.length; i++) {
            if (i > 0) error += "\n";
            error += errors[i];
        }
        alert(error);
    }
    return !errors.length;
}

Form.prototype.validate = function(type, field) {
    var valid;
    switch (type) {
        case 'required':
            if (jQuery.trim(field.attr('value')) == '') return this.capitalize(field.attr('name')) + ' is required.';
            break;
        case 'email':
            valid = String(field.attr('value')).search(/^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/) != -1;
            if (!valid) return 'Please enter a valid email address.';
            break;
    }
    return true;
}

Form.prototype.onSubmit = function(event) {
    if (!this.valid()) {
        event.preventDefault();
        return false;
    }
    if (this.settings.XHR) {
        this.form.ajaxSubmit(this.closure('onComplete'));
        event.preventDefault();
        return false;
    }
    return true;
}

Form.prototype.onComplete = function(a) {
    if (jQuery.trim(this.settings.replace).length > 0) {
        this.form.parent().empty().html('<p class="thanks">' + this.settings.replace + '</p>');
    }
}

Form.prototype.closure = function(method) {
    var obj = this;
    return function(arg1, arg2, arg3) { obj[method](arg1, arg2, arg3) };
}

Form.prototype.closureEvent = function(event) {
    var obj = this;
    return function(event) { obj[event.data.method](event) };
}

Form.prototype.capitalize = function(str) {
    return str.charAt(0).toUpperCase() + str.substr(1);
}

/**********************************************************************
* GALLERY HANDLER
*********************************************************************/
var ImageRotator = {
    initialize: function(images) {
        this.container = $(images.parent()[0]);
        this.images = images;
        if (!this.valid()) return;
        this.current = 0;
        this.aligned = [];
        this.moving = false;
        this.prepare();
        this.realign();
    },
    valid: function() {
        if (this.images.length == 1) {
            $(this.images[0]).css({ left: 0, top: 0 });
            $(this.container.parent().find('.controls')[0]).remove();
            return false;
        }
        return true;
    },
    prepare: function(event) {
        $(this.container.parent().find('.controls .next')[0]).bind('click', { obj: this }, function(event) { event.data.obj.move('next'); });
        $(this.container.parent().find('.controls .prev')[0]).bind('click', { obj: this }, function(event) { event.data.obj.move('prev'); });
        $(this.container.find('.glass')[0]).bind('click', { obj: this }, function(event) { $(event.data.obj.images[event.data.obj.current]).click(); });
    },
    realign: function() {
        $(this.images[this.current]).css({ left: 0, top: 0 });
        this.aligned[0] = $((this.current == 0 ? this.images[this.images.length - 1] : this.images[this.current - 1]));
        this.aligned[1] = $(this.images[this.current]);
        this.aligned[2] = $((this.current == this.images.length - 1 ? this.images[0] : this.images[this.current + 1]));
        $(this.container.parent().find('.controls .title')[0]).html($(this.images[this.current]).attr('title'));
    },
    move: function(which) {
        if (this.moving) return;
        this.moving = true;
        if (which == 'prev') this.aligned[0].css({ left: '-' + this.container.width() + 'px', top: 0 }).animate({ left: 0 }, this.moveComplete(this));
        this.aligned[1].animate({ left: which == 'next' ? (-this.container.width()) + 'px' : this.container.width() + 'px' });
        if (which == 'next') this.aligned[2].css({ left: this.container.width() + 'px', top: 0 }).animate({ left: 0 }, this.moveComplete(this));
        this.current = (which == 'next') ? (this.current == this.images.length - 1 ? 0 : this.current + 1) : (this.current == 0 ? this.images.length - 1 : this.current - 1);
    },
    moveComplete: function(obj) {
        return function() { obj.moving = false; obj.realign(); };
    }
};

/**********************************************************************
* COUNTDOWN HANDLER
*********************************************************************/
var Countdown = {
    initialize: function(container) {
        var title = container.attr('title');
        var point = title.indexOf('|');
        if (point == -1) {
            time_left = title;
            text = '';
        } else {
            time_left = title.substring(0, point);
            text = title.substring(point + 1);
        }
        container.attr('title', '');
        container.find('.content').flash({
            src: Config.countdown_url,
            width: '100%',
            height: 205,
            wmode: 'transparent',
            flashvars: {
                cdate: time_left,
                ct: text
            }
        }, {
            version: 7
        });
    }
};

/**********************************************************************
* ZEPPELIN HANDLER
*********************************************************************/
var Zeppelin = {
    url: {
        main: Config.zeppelin_url_main,
        sign_in: Config.zeppelin_url_signin,
        sign_out: Config.zeppelin_url_signout,
        query_string: Config.zeppelin_query_string
    },
    initialize: function(container) {
        this.container = container;
        this.load();
        return;
        this.preload($.bind(this, this.preload_complete));
    },
    preload: function(onComplete) {
        var IsDistributed = $.cookie('IsDistributed');
        if (IsDistributed == true) {
            this.load();
        } else {
            var urls = (typeof $.cookie('DistributedUrls') == 'string') ? $.cookie('DistributedUrls') : '';
            this.preload_urls = urls.split(' ');
            this.preload_count = this.preload_urls.length;
            this.preload_done = 0;
            for (var i = 0; i < this.preload_count; i++) {
                var iframe = $('<iframe></iframe>')
					.addClass('ZeppelinPreloader')
					.appendTo($('body'))
					.css('left', i * 100);
                iframe
					.load($.bind(this, this.preload_update, iframe, onComplete))
					.attr('src', this.preload_urls[i]);
            }
        }
    },
    preload_update: function(e, iframe, onComplete) {
        this.preload_done++;
        if (this.preload_done == this.preload_count) {
            if (onComplete) onComplete();
        }
    },
    preload_complete: function() {
        $('.ZeppelinPreloader').remove();
        $.cookie('IsDistributed', true);
        $.cookie('DistributedUrls', null);
        this.load();
    },
    load: function() {
        this.content = this.container.find('.content');
        this.iframe = this.createIframe();
        this.visible = false;
        this.controller = {
            loading: this.container.find('.loading'),
            username: this.container.find('.username'),
            separator: this.container.find('.separator'),
            signIn: this.container.find('.signIn'),
            signOut: this.container.find('.signOut'),
            open: this.container.find('.open'),
            close: this.container.find('.close'),
            control: this.container.find('.control')
        };
        this.query_string = Config.zeppelin_query_string;
        this.openOnResize = 0;
        this.addEvents();
        this.clear();
        this.controller.loading.show();
        this.stateRestore();
    },
    addEvents: function() {
        this.controller.signIn.click(this.closure('signIn'));
        this.controller.signOut.click(this.closure('signOut'));
        this.controller.open.click(this.closureNoArgs('open'));
        this.controller.close.click(this.closureNoArgs('close'));
        return this;
    },
    open: function(height, fast) {
        this.resize((height || this.height));
        if (!this.visible) {
            this.visible = true;
            if (fast == true) {
                this.content.show();
                var f = $('div.Zeppelin div.content iframe')[0];
                var doc = f.contentWindow ? f.contentWindow.document :
				f.contentDocument ? f.contentDocument : f.document;
                $('input#frmPassword', doc).focus();
            } else {
                this.content.slideDown('slow', function() {
                    $(this).delay(200, function() {
                        var f = $('div.Zeppelin div.content iframe')[0];
                        var doc = f.contentWindow ? f.contentWindow.document :
						f.contentDocument ? f.contentDocument : f.document;
                        $('input#frmPassword', doc).focus();
                    });
                });
            }
            this.controller.open.hide();
            this.controller.close.show();

        }
        this.stateSave();
        return this;
    },
    close: function(height) {
        this.visible = false;
        this.content.slideUp('slow', this.closureArgs('resize', (height || this.height)));
        this.controller.close.hide();
        this.controller.open.show();
        this.stateSave();
        return this;
    },
    signIn: function() {
        if (this.visible) {
            this.close();
        } else {
            this.openOnResize = 1;
            this.iframe.attr('src', this.url.sign_in + this.query_string);
        }
        return this;
    },
    signOut: function() {
        this.close();
        this.iframe.attr('src', this.url.sign_out + this.query_string);
        return this;
    },
    resize: function(height) {
        if (this.openOnResize > 0) {
            var fast = (this.openOnResize == 2) ? true : false;
            this.openOnResize = 0;
            this.open(height, fast);
        } else {
            this.height = height;
            if (this.visible) {
                this.content.animate({ height: this.height }, 'slow');
            } else {
                this.content.css('height', this.height);
            }
            this.stateSave();
        }
        return this;
    },
    clear: function() {
        for (i in this.controller) {
            this.controller[i].hide();
        }
        return this;
    },
    createIframe: function() {
        this.content.html('<iframe src="about:blank" frameborder="0" scrolling="no" border="0"></iframe>');
        return this.content.find('iframe');
    },
    setLoggedInStatus: function(logged_in, username) {
        this.clear();
        this.controller.separator.show();
        this.controller.username.show();
        if (logged_in) {
            this.controller.signIn.hide();
            this.controller.signOut.show();
            this.controller.username.html('Hello ' + username + '!');
            this.controller.control.show();
            if (this.visible) {
                this.controller.close.show();
            } else {
                this.controller.open.show();
            }
        } else {
            this.controller.username.html('Hello Guest!');
            this.controller.signIn.show();
            this.controller.signOut.hide();
            this.controller.control.hide();
        }
        return this;
    },
    closure: function(method) {
        var obj = this;
        return function(arg1, arg2, arg3) { obj[method](arg1, arg2, arg3) };
    },
    closureArgs: function(method, arg1, arg2, arg3) {
        var obj = this;
        return function() { obj[method](arg1, arg2, arg3); };
    },
    closureNoArgs: function(method) {
        var obj = this;
        return function() { obj[method](); };
    },
    stateSave: function() {
        $.cookie('zeppelin_height', (this.visible ? this.height : 0));
    },
    stateRestore: function() {
        var height = $.cookie('zeppelin_height');
        if (height && height > 0) {
            this.openOnResize = 2;
        }
        this.iframe.attr('src', this.url.main + this.query_string);
    }
};

/**********************************************************************
* BRIGHTCOVE HANDLER
*********************************************************************/
var BrightCove = {
    initialize: function(movies) {
        for (var i = 0; i < movies.length; i++) {
            var id = $(movies[i]).attr('id').toString();
            id = id.substring(id.lastIndexOf('_') + 1, id.length);
            var code = $('#Lazy_BRIGHTCOVE_' + id).html();
            $('#Lazy_BRIGHTCOVE_' + id).remove();
            $('#MODULE_BRIGHTCOVE_' + id + ' .content').html(code);
        }
    }
};

/**********************************************************************
* SEARCH HANDLER
*********************************************************************/
var Search = {
    initialize: function(form) {
        this.url_live = Config.search_url_live;
        this.url_static = Config.search_url_static;
        this.form = form;
        this.input = form.find('input[type=text]');
        this.delay = null;
        this.request = null;
        this.data = null;
        this.visible = false;
        this.selected = -1;
        this.more = false;
        this.prepare();
    },
    prepare: function() {
        this.form.bind('submit', function(event) {
            event.preventDefault();
            var val = (Search.input.attr('value') == 'Search the site, blog, products') ? '' : Search.input.attr('value');
            window.location = Search.url_static + '?q=' + val;
            return false;
        });
        $(document).click(function(event) {
            if (Search.visible) {
                var l = Search.list.offset().left;
                var r = l + Search.list.width();
                var t = Search.input.offset().top;
                var b = t + Search.list.height();
                if ((event.pageX < l || event.pageX > r || event.pageY < t || event.pageY > b)) {
                    Search.hide();
                }
            }
        });
        this.input.bind('click.search', function() {
            if (!$(this).attr('activated')) {
                $(this).attr({ activated: true, value: '' });
            }
        }).bind('keyup.search', function(event) {
            if (event.which == 13) {
                if (Search.selected == -1) {
                    window.location = Search.url_static + '?q=' + Search.input.attr('value');
                } else {
                    Search.list.find('li:eq(' + Search.selected + ')').click();
                }
            } else if (event.which == 27) {
                Search.hide();
            } else if (event.which == 40) {
                if (Search.visible) {
                    Search.scrollDown();
                } else if (Search.data && Search.data.results.length > 0) {
                    Search.show();
                }
            } else if (event.which == 38) {
                if (Search.visible) {
                    Search.scrollUp();
                } else if (Search.data && Search.data.results.length > 0) {
                    Search.show();
                }
            } else if (event.which > 48 || event.which == 8) {
                Search.onPress();
            }
        }).bind('keypress.search', function(event) {
            if (event.which == 13) {
                event.preventDefault();
                return false;
            }
        });
    },
    onPress: function() {
        if (jQuery.trim(this.input.attr('value')).length >= 3) {
            clearTimeout(this.delay);
            this.delay = setTimeout(function() {
                Search.query();
            }, 500);
        }
    },
    query: function() {
        if (this.request) this.request.abort();
        this.request = $.ajax({
            url: this.url_live,
            dataType: 'json',
            type: 'GET',
            data: "q=" + this.input.attr('value') + '&type=live',
            success: function(data) {
                Search.data = data;
                Search.show();
            }
        });
    },
    create: function() {
        this.list = $(document.createElement('ul'))
						.attr('id', 'search_results')
						.css('display', 'none')
						.appendTo('.Container');
    },
    show: function() {
        if (this.data == null) return;
        if (this.list == null) {
            this.create();
        }
        this.list.empty();
        if (this.data.count == 0) {
            this.hide();
            return;
        }
        for (var i = 0; i < this.data.results.length; i++) {
            var result = this.data.results[i];
            var cls = '';
            if (i == 0) {
                var cls = ' class="first"';
            } else if (i == this.data.results.length - 1) {
                var cls = ' class="last"';
            }
            var li = $(
				'<li id="search_result_' + i + '" ' + cls + '>' +
					'<div class="title">' + ((result.title.length > 36) ? result.title.substring(0, 34) + '...' : result.title) + '</div>' +
					'<div class="summary">' + result.summary + '</div>' +
				'</li>'
			);
            li.attr('url', result.url);
            li.click(function() {
                window.location = $(this).attr('url');
            }).mouseover(function() {
                Search.select($(this).attr('id').replace('search_result_', ''));
            }).mouseout(function() {
                Search.unselectAll();
            });
            this.list.append(li);
        }
        if (this.data.count > this.data.results.length) {
            this.more = true;
            var total = $('<li class="total"><b>' + (this.data.count - this.data.results.length) + '</b> more results...</li>');
            total.click(function() {
                window.location = Search.url_static + '?q=' + Search.input.attr('value');
            });
            this.list.append(total);
        } else {
            this.more = false;
        }
        this.list.show();
        this.visible = true;
    },
    hide: function() {
        if (this.list == null) this.create();
        this.list.hide();
        this.visible = false;
    },
    scrollUp: function() {
        if (this.selected == -1) {
            this.selectLast();
            return;
        }
        if (this.selected == 0) {
            this.selectInput();
            return;
        }
        var selectNext = false;
        var all = this.list.find('li');
        for (var i = all.length - 1; i > -1; i--) {
            if (i == this.selected) {
                selectNext = true;
                continue;
            }
            if (selectNext) {
                this.select(i, all[i]);
                break;
            }
        }
    },
    scrollDown: function() {
        if (this.selected == -1) {
            this.selectFirst();
            return;
        }
        if (this.selected == this.data.results.length - 1) {
            this.selectInput();
            return;
        }
        var selectNext = false;
        var all = this.list.find('li');
        for (var i = 0; i < all.length; i++) {
            if (i == all.length - 1 && this.more) {
                selectNext = false;
                break;
            }
            if (i == this.selected) {
                selectNext = true;
                continue;
            }
            if (selectNext) {
                this.select(i, all[i]);
                break;
            }
        }
    },
    select: function(i) {
        this.unselectAll();
        this.list.find('li:eq(' + i + ')').addClass('selected');
        this.selected = i;
    },
    selectFirst: function() {
        this.unselectAll();
        this.selected = 0;
        this.list.find('li:first').addClass('selected');
    },
    selectLast: function() {
        this.unselectAll();
        if (this.more) {
            this.selected = this.data.results.length - 1;
            this.list.find('li:eq(' + this.selected + ')').addClass('selected');
        } else {
            this.selected = this.data.results.length - 1;
            this.list.find('li:last').addClass('selected');
        }
    },
    selectInput: function() {
        this.unselectAll();
        this.selected = -1;
        this.input[0].select();
    },
    unselectAll: function() {
        this.list.find('li').removeClass('selected');
    }
};

/**********************************************************************
* INITIALIZE
*********************************************************************/
$(document).ready(function() {
	$('a.freeman').click(function() {
	    $('form.freeman').submit();
	    return false;
	});
    if (!$('.MODULE_SOCIAL').length) {
        $('.PrintPage').css('right', 0);
    }

    // Search Handler
    if ($('#search')) {
        Search.initialize($('#search'));
    }

    // Form Handler
    var forms = $('form');
    for (var i = 0; i < forms.length; i++) {
        new Form(forms[i]);
    }

    // Image Rotator
    var theme = $('meta[name=theme]').attr('content');
    var images = $('.MODULE_GALLERY .screen a');
    if (images.length > 0) {
        $('.MODULE_GALLERY .screen a').lightBox({
            imageLoading: 'assets/img/' + theme + '/lightbox_ico_loading.gif',
            imageBtnClose: 'assets/img/' + theme + '/lightbox_btn_close.gif',
            imageBtnPrev: 'assets/img/' + theme + '/lightbox_btn_prev.gif',
            imageBtnNext: 'assets/img/' + theme + '/lightbox_btn_next.gif',
            imageBlank: 'assets/img/' + theme + '/lightbox_blank.gif'
        });
        ImageRotator.initialize(images);
    }

    // Countdown
    if ($('.MODULE_COUNTDOWN').length) {
        Countdown.initialize($('.MODULE_COUNTDOWN'));
    }

    // BrightCove
    if ($('.MODULE_BRIGHTCOVE').length) {
        BrightCove.initialize($('.MODULE_BRIGHTCOVE'));
    }

    // Zeppelin
    if ($('.Zeppelin').length) {
        Zeppelin.initialize($('.Zeppelin'));
    }

    // Handle external links.
    $('a[@href^=http]').each(function() {
        if (this.href.indexOf(location.hostname) == -1) {
            $(this).attr('target', '_blank');
        }
    });

    // 5 Part Module
    if ($('.MODULE_5PART').length) {
        $('.MODULE_5PART').equalHeights();
    }

});

$(window).bind('beforeunload', function() {
    $.ajax({ url: proxyUrl + '/logout.aspx', async: false });
});

