﻿var Meridian = {};
var _gaq = _gaq || [];

if (typeof $.getItemByProperty === 'undefined') {
	$.getItemByProperty = function (array, property, value, fromIndex) {
		var i, j;
		if (fromIndex === null || typeof fromIndex === 'undefined') {
			fromIndex = 0;
		} else if (fromIndex < 0) {
			fromIndex = Math.max(0, array.length + fromIndex);
		}
		for (i = fromIndex, j = array.length; i < j; i++) {
			if (array[i][property] === value) {
				return array[i];
			}
		}
		return -1;
	};
}

$(function () {
	Meridian.Floodlight.init();
	Meridian.GoogleAnalytics({ enabled: Meridian.isProduction, accountId: 'UA-3263907-11' });
	Meridian.Nav.init();
	Meridian.TalkToUs.init();
	Meridian.ContentLinks.init();
	Meridian.Banners.init();
	Meridian.LookingFor.init();
	Meridian.SplashCountdown.init();
	$(".searchButton").click(function(e) {
		e.preventDefault();
		window.location.href = "http://" + window.location.hostname + "/search/Pages/default.aspx?k=" + $("#k").val();
	});
	// show scrollbars for those with a resolution smaller than the target
	if (screen.width < 1024) {
	    $("body").css("overflow-x", "visible");
	}
	//$("span:empty").remove();	
	//$("p:empty").remove();
	
	$('#mini-rate-list td.title').each(function() {
		if($(this).text() === '5 Year Closed') {
			$(this).add($(this).prev('td')).addClass('highlight');
		}
	});
	
	$('.accordian h5').wrapInner('<a href="#" />').each(function() {
		$(this).children('a').click(function(e) {
			e.preventDefault();
			var i = 0;
			$(this).parent().nextUntil('h5').each(function() {
				++i;
				var that$ = $(this),
					duration = 100;
				setTimeout(function() {
					if(that$.is(':visible') === true) {
						that$.slideUp(duration);
					} else {
						that$.slideDown(duration);
					}
				}, duration * i);			
			});
		}).end().nextUntil('h5').hide();
	});
});

Meridian.isProduction = (function() {
	return (/meridiancu\.ca$/i).test(window.location.hostname);
}());

Meridian.isDcu = (function() {
	var pathParts = window.location.pathname.split("/");
	if (pathParts.length >= 2 && pathParts[1].toLowerCase() === 'dcu') {
		return true;
	}
	return false;
}());

Meridian.SplashCountdown = {
    init: function () {
        var date,
			markup = '',
			container$ = $('#splash-countdown');

		if(container$.length) {
			date = new Date(2012, 1, 29, 23, 59, 59);

			markup += '<span id="splash-countdown-days" title="{dl}">{dn}</span>';
			markup += '<span id="splash-countdown-hours" title="{hl}">{hn}</span>';
			markup += '<span id="splash-countdown-minutes" title="{ml}">{mn}</span>';
			markup += '<span id="splash-countdown-seconds" title="{sl}">{sn}</span>';
		
	        container$.countdown({
	            until: date,
	            layout: markup,
	            format: 'DHMS'
	        });
	    }
    }
};

Meridian.Floodlight = {
	map: { 
		'/Pages/welcome.aspx': 'homep013',
		'/personal-banking/why/Pages/Why-Meridian.aspx': 'perso257',
		'/personal-banking/mortgages/Pages/default.aspx': 'mortg535',
		'/rates/accounts/Pages/default.aspx': 'rates993',
		'/find-us/our-locations/Pages/default.aspx': 'findu669',
		'/meridian/why-meridian/Pages/index.aspx': 'whyme078',
		'/personal-banking/ways-to-bank/Online%20Banking/Pages/default.aspx ': 'onlin585',
		'/personal-banking/accounts/chequing/Pages/default.aspx': 'accou059',
		'/personal-banking/borrowing/Pages/default.aspx': 'borro117',
		'/personal-banking/calculators/Pages/default.aspx': 'calcu638'
	},
	track: function (cat) {
		var axel = Math.random(),
			a = axel * 10000000000000,
			markup = '<iframe src="http://fls.doubleclick.net/activityi;src=2918287;type=merid709;cat=' + cat.toString() + ';ord=' + a.toString() + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>'; 
		$('body').prepend(markup); 
	},
	init: function() {
		var cat = this.map[document.location.pathname];
		if(cat && Meridian.isProduction === true) {
			this.track(cat);
		}
	}
};

Meridian.GoogleAnalytics = function (options) {
	var settings = $.extend({
			enabled: true,
			
			// Google account ID e.g. UA-0000000-00
			accountId: null,
			
			// clickable elements to attach events to
			elements: ['a', 'area'],
			
			// collection of link types, each of which may be 
			// identified and click-handled using custom logic
			linkTypes: {
				outbound: {
					cssClass: 'outbound',
					identify: function (obj) {
						return !obj.href.match(/^mailto\:/) && (obj.hostname !== location.hostname);
					},
					onClick: function () {
						_gaq.push(['_trackEvent', 'OutboundLink', 'Click', $(this).attr('href')]);
					}
				},
				download: {
					cssClass: 'download',
					identify: function (obj) {
						var // download filetypes may be extended
							ext = ['pdf', 'doc'], 
							pattern = (function () {
								var p = '';
								$.each(ext, function(index, value) {
									p += '\\.' + value + '|';
								});
								p = p.substring(0, p.length - 1);
								return '(' + p + ')$';
							}()),
							m = obj.href.match(new RegExp(pattern, 'i'));
							
						return (m && m.length >= 1);
					},
					onClick: function () {
						var url = $(this).attr("href"),
							ext = url.split('.').pop().toUpperCase();
						_gaq.push(['_trackEvent', 'Downloads', ext, url]);
					}
				}
			}
		}, options || {}),
		identifyElements = function() {
			$.each(settings.linkTypes, function (key, obj) {
				$.expr[':'][key] = obj.identify;
				markElements(obj.cssClass);
			});
		},
		markElements = function (className) {
			$.each(settings.elements, function(index, value) {
				$(value + ':' + className).addClass(className);
			});
		},
		attachHandlers = function() {
			$.each(settings.linkTypes, function (key, obj) {
				$.each(settings.elements, function(index, value) {
					$(value + ':' + key).click(obj.onClick);
				});
			});
		};

	identifyElements();

	if (settings.enabled === true) {
		if(!settings.accountId) {
			throw 'You must provide an account ID';
			return false;
		}
		attachHandlers();
		
		_gaq.push(['_setAccount', settings.accountId]);
		_gaq.push(['_trackPageview']);
		(function() {
			var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
			ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
			var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
		}());		
	}
};

Meridian.Nav = {
    $navContainer: null,
    expandableSrc: '<img src="/SiteAssets/images/nav_expandable.gif" alt="Expand" />',
    expandableSelectedSrc: '<img src="/SiteAssets/images/nav_expandable_selected.gif" alt="Expand" />',
    expandedSrc: '<img src="/SiteAssets/images/nav_expanded.gif" alt="Contract" />',
    expandedSelectedSrc: '<img src="/SiteAssets/images/nav_expanded_selected.gif" alt="Contract" />',
    init: function () {
        this.setTopNav();
        this.$navContainer = $("#nav");
        this.addExpandables();
		this.$navContainer.find("ul > li a").click(this.onListItemClick);
		$(".selected", this.$navContainer).closest("li.expandable").find("img").trigger("click");
    },
    setTopNav: function () {
        var pathParts = window.location.pathname.split("/"),
			rootSiteIndex = Meridian.isDcu ? 2 : 1;
        if (pathParts.length >= 2 && pathParts[1] !== "") {
            $("#" + pathParts[rootSiteIndex].toLowerCase()).closest("li").addClass("active");
        }
    },
    addExpandables: function () {
        this.$navContainer.find("ul > li:has(ul)").each(function () {
            var img = ($(this).hasClass("expanded")) ? Meridian.Nav.expandedSrc : Meridian.Nav.expandableSrc;
            $(this).addClass("expandable").find("> a").append(img);
        });
    },
    onListItemClick: function (e) {
        var $target = $(e.target);
        if ($target.is("img")) {
            e.preventDefault();
            var $parent = $(this).closest("li");
            if ($parent.hasClass("expanded")) {
                $parent.removeClass("expanded");
                if($parent.hasClass("selected")) {
					$target.replaceWith(Meridian.Nav.expandableSelectedSrc);
                } else {
					$target.replaceWith(Meridian.Nav.expandableSrc);
	            }
            } else {
                $parent.addClass("expanded");
                if($parent.hasClass("selected")) {
	                $target.replaceWith(Meridian.Nav.expandedSelectedSrc);
	            } else {
					$target.replaceWith(Meridian.Nav.expandedSrc);
	            }
            }
        }
    }
};

Meridian.TalkToUs = {
    $talkToUsContent: null,
    init: function () {
        this.$talkToUsContent = $("#talk-to-us_content");
        // listeners
        $("#talk-to-us li").click(this.onTabClick);
        $("#locate-a-branch").change(this.onBranchChange);
    },
    onTabClick: function () {
        $(this).addClass("active").siblings().removeClass("active");
        Meridian.TalkToUs.$talkToUsContent.find(">div:eq(" + $(this).index() + ")").show().siblings().hide();
        return false;
    },
    onBranchChange: function () {
        var idx = $(this).find(":selected").index();
        if (idx === 0) {
            $("#branches").addClass("hide");
        } else {
            $("#branches").removeClass("hide").find("> div:eq(" + (idx - 1).toString() + ")").removeClass("hide").siblings().addClass("hide");
        }
    }

};

Meridian.ContentLinks = {
    fontSize: 100,
    fontSizeIncrement: 10,
    init: function () {
        $("#print-page").click(this.onPrintClick);
        $("#font-size-increase").click(this.onFontSizeIncreaseClick);
        $("#font-size-decrease").click(this.onFontSizeDecreaseClick);
    },
    changeFontSize: function(change) {
        Meridian.ContentLinks.fontSize += change;
        $(".fontResize").css("font-size", Meridian.ContentLinks.fontSize + "%");
    },
    onPrintClick: function () {
        window.print();
        return false;
    },
    onFontSizeIncreaseClick: function () {        
        Meridian.ContentLinks.changeFontSize(Meridian.ContentLinks.fontSizeIncrement);
        return false;
    },
    onFontSizeDecreaseClick: function () {        
        Meridian.ContentLinks.changeFontSize(-Meridian.ContentLinks.fontSizeIncrement);
        return false;
    }
};

Meridian.Banners = {
    $bannerNav: null,
    $bannerContainer: null,
	$activeDot: null,
	$activeBanner: null,
    numberOfBanners: 0,
    numberOfBannersShown: 1,
    activeBannerIndex: 0,
    duration: 20000,
    fadeInDuration: 500,
    fadeOutDuration: 500,
    bannerLoaded: null,
    bannerUnloaded: null,
    isTransitioning: false,
    init: function () {
        this.$bannerNav = $("#banner-nav");
        if (this.$bannerNav.length) {
            this.$bannerContainer = $("#banner-container");
            this.preload();
            this.numberOfBanners = $("a", this.$bannerNav).length;
            this.activeBannerIndex = $(".active", this.$bannerNav).index();        
            this.checkForUrl();          
			this.setActiveBanner();
            if (this.numberOfBanners > 1) {
	            // show navigation
	            this.$bannerNav.show(); 
	            // handle events
	            $("a", this.$bannerNav).click(this.onNavClick);  
	            
			this.slideShow();
	        }
        }
    },    
    preload: function () {
        var i, image, 
			preloaders = this.$bannerNav.find("a:not(.active)").map(function () {
            return $(this).attr("rel");
        });

        if (preloaders) {
            image = new Image();
            for (i = 0; i < preloaders.length; i++) {
                image.src = preloaders[i];
            }
        }
    },
    checkForUrl: function() {
		// temporary: fixes bug where url not attached to the default banner, and a blank url attached to banners without a url
        var $imgDot = $("a:eq(" + Meridian.Banners.activeBannerIndex + ")", Meridian.Banners.$bannerNav),
			$banner = Meridian.Banners.$bannerContainer.find("img:eq(0)");

		if ($banner.parent().is("a")) {
			$banner.parent().attr("href", $imgDot.attr("href"));
		} else {
			$banner.wrap("<a href='" + $imgDot.attr("href") + "' />");
		}
    },
    slideShow: function () {

        Meridian.Banners.bannerTimerId = setInterval(function () {
            if (Meridian.Banners.numberOfBannersShown === Meridian.Banners.numberOfBanners) {
                clearInterval(Meridian.Banners.bannerTimerId);
            } else {
                Meridian.Banners.numberOfBannersShown++;
                Meridian.Banners.activeBannerIndex++;
                if (Meridian.Banners.activeBannerIndex === Meridian.Banners.numberOfBanners) {
                    Meridian.Banners.activeBannerIndex = 0;
                }
                Meridian.Banners.loadBanner();
            }
        }, Meridian.Banners.duration);

    },
    loadVideo: function () {
    	var videoUrl = this.$activeDot.attr('data-video-url'),
    		container$ = this.$activeBanner.closest('div'),
    		link$ = container$.find('a:first');
		if(videoUrl && container$.find('iframe').length === 0) {
			container$.append('<iframe width="396" height="223" src="' + videoUrl + '" frameborder="0" allowfullscreen />');
			link$.append('<h1>' + this.$activeDot.attr('data-title') + '</h1>');
			link$.append('<p>' + this.$activeDot.attr('data-description') + '</p>');
			$('#body').css('margin-top', 351);
		}
    },
    setActiveBanner: function () {
        this.$activeDot = $("a:eq(" + Meridian.Banners.activeBannerIndex + ")", Meridian.Banners.$bannerNav);
		this.$activeBanner = Meridian.Banners.$bannerContainer.find("img:eq(0)");
        this.loadVideo();
    },
    loadBanner: function () {
		var that = this;
 
		this.setActiveBanner();
        
		// do not allow banner change while one is already in progress
		if(Meridian.Banners.isTransitioning === false) {
			Meridian.Banners.isTransitioning = true;
		}

       	if (typeof Meridian.Banners.bannerUnloaded === 'function') {
            Meridian.Banners.bannerUnloaded(this.$activeBanner.attr("src"));
        } 
        
		this.$activeBanner.closest('div').find('iframe').fadeOut(Meridian.Banners.fadeOutDuration).remove();
		this.loadVideo();
		
		this.$activeBanner.fadeOut(Meridian.Banners.fadeOutDuration, function () {
	        // remove anchor if it exists
	        if (that.$activeBanner.parent().is("a")) {
	            that.$activeBanner.unwrap();
	        }          
	        
	        // set banner
	        that.$activeBanner.attr({ 
					src: that.$activeDot.attr("rel"), 
					title: that.$activeDot.attr("title"), 
					alt: that.$activeDot.attr("title") 
				}).fadeIn(Meridian.Banners.fadeInDuration, function () {
				that.loadVideo();
	                // wrap with anchor if one exists
	                if (that.$activeDot.attr("href") !== that.$activeDot.attr("rel")) {
	                    that.$activeBanner.wrap("<a href='" + that.$activeDot.attr("href") + "' />");
	                }
	                               
     				if (typeof Meridian.Banners.bannerLoaded === 'function') {
	                    Meridian.Banners.bannerLoaded(that.$activeDot.attr("rel"));
	                }	                
	                Meridian.Banners.isTransitioning = false;
				});
	
	        // set dots
	        that.$activeDot.addClass("active").siblings().removeClass("active");		
		});
    },
    onNavClick: function (e) {
        e.preventDefault();
        if (!$(this).hasClass("active") && Meridian.Banners.isTransitioning !== true) {
            clearInterval(Meridian.Banners.bannerTimerId);
            Meridian.Banners.activeBannerIndex = $(this).index();
            $(this).addClass("active").siblings().removeClass("active");
            Meridian.Banners.loadBanner();
        }
    }
};

Meridian.LookingFor = {
    init: function () {
        var $toggle = $("#lookingFor-title");
        if ($toggle.length) {
            $toggle.click(function () {
                $("#lookingFor-links").toggle();
                return false;
            });
        }
    }
};

var SoapEnvelope = (function () {
	var parseParameters = function (parameters) {
			var params = '',
				i,
				length;  
			if (typeof parameters === 'object') {
				// check if we were provided an array or an object
				if (typeof parameters.push === 'function') {
					for (i = 0, length = parameters.length; i < length; i += 2) {
						params += '<' + parameters[i] + '>' + parameters[i + 1] + '</' + parameters[i] + '>';  
					}
				} else {
					$.each(parameters, function (key, value) {
						params += '<' + key + '>' + value + '</' + key + '>';
					});  
				}
			}  
			return params;  
		},
		create = function (action, parameters) {
		    var SOAP = '<?xml version="1.0" encoding="utf-8"?>';
			SOAP += '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
	        SOAP += '<soap:Body>';
	        SOAP += '<' + action + ' xmlns="http://schemas.microsoft.com/sharepoint/soap/">';
	        SOAP += parseParameters(parameters);
	        SOAP += '</' + action + '>';
	        SOAP += '</soap:Body>';
	        SOAP += '</soap:Envelope>';
			return SOAP; 
		},
		getRows = function (action, parameters, callback) {
			var rows$,
				soapEnv = create(action, parameters);
							
			$.ajax({
		        type: 'POST',
		        url: '/_vti_bin/lists.asmx',
		        dataType: 'xml',
		        contentType: 'text/xml; charset="utf-8"',
		        data: soapEnv,
		        async: false,
		        error: function (XMLHttpRequest, textStatus, errorThrown) {
		            alert('There was a problem retrieving the data. Please try again.');
		        },
		        success: function (data, textStatus, XMLHttpRequest) {
					rows$ = $(data).find('[nodeName=z:row]');
		        }
		    });  
		    return rows$;
		};
	return { getRows: getRows };
}());

var Rates = (function () {
	var getCategories = function (options) {
		var settings = $.extend({
				RateCategoryId: []
			}, options || {}),
			query,
			rows$,
			i,
			categories = [];
			
		if (typeof settings.RateCategoryId === 'number') {
			settings.RateCategoryId = [settings.RateCategoryId];				
		}
		if (!(settings.RateCategoryId instanceof Array)) {
			settings.RateCategoryId = [];
		}

		query = '<Query>';
		query += '<Where>';
		if (settings.RateCategoryId.length > 0) {
			query += '<In>';
			query += '<FieldRef Name="ID" /><Values>';
			for (i = 0; i < settings.RateCategoryId.length; ++i) {
				query += '<Value Type="Number">' + settings.RateCategoryId[i] + '</Value>';
			}
			query += '</Values></In>';
		}
		query += '</Where>';
		query += '</Query>';

		rows$ = SoapEnvelope.getRows('GetListItems', { 
			listName: 'RateCategories', 
			rowLimit: 0,
			query: query
		});
				
		if (typeof rows$ !== 'undefined' && rows$.length > 0) {
			rows$.each(function () {
				var categorie = {};
				categorie.ID = +$(this).attr('ows_ID');
				categorie.title = $(this).attr('ows_Title');
				categories.push(categorie);
			});
		}
		return categories;
	};
	var getGroups = function (options) {
		var settings = $.extend({
				RateCategoryId : [],
				RateGroupId: []
			}, options || {}),
			query,
			rows$,
			i,
			groups = [];
	
		if (typeof settings.RateCategoryId === 'number') {
			settings.RateCategoryId = [settings.RateCategoryId];				
		}
		if (typeof settings.RateGroupId === 'number') {
			settings.RateGroupId = [settings.RateGroupId];
		}
	
		if (!(settings.RateCategoryId instanceof Array)) {
			settings.RateCategoryId = [];
		}
		if (!(settings.RateGroupId instanceof Array)) {
			settings.RateGroupId = [];
		}

		if (settings.RateCategoryId.length > 0 || settings.RateGroupId.length > 0) {
			query = '<Query>';
			query += '<Where>';
			if (settings.RateCategoryId.length > 0 && settings.RateGroupId.length > 0) {
				query += '<And>';
			}
			if (settings.RateCategoryId.length > 0) {
				query += '<In>';
				query += '<FieldRef Name="Category" LookupId="TRUE"/><Values>';
				for (i = 0; i < settings.RateCategoryId.length; ++i) {
					query += '<Value Type="Lookup">' + settings.RateCategoryId[i] + '</Value>';
				}
				query += '</Values></In>';
			}
			if (settings.RateGroupId.length > 0) {
				query += '<In>';
				query += '<FieldRef Name="ID" /><Values>';
				for (i = 0; i < settings.RateGroupId.length; ++i) {
					query += '<Value Type="Number">' + settings.RateGroupId[i] + '</Value>';
				}
				query += '</Values></In>';
			}	
			if (settings.RateCategoryId > 0 && settings.RateGroupId > 0) {
				query += '</And>';
			}
			query += '</Where>';
			query += '</Query>';
		}
		rows$ = SoapEnvelope.getRows('GetListItems', { 
			listName: 'RateGroups', 
			rowLimit: 0,
			query: query
		});
				
		if (typeof rows$ !== 'undefined' && rows$.length > 0) {
			rows$.each(function () {
				var group = {};
				group.ID = +$(this).attr('ows_ID');
				group.title = $(this).attr('ows_Title');
				group.CategoryID = +$(this).attr('ows_Category').match(/^\d+/);
				group.Category = $(this).attr('ows_Category').replace(/^\d+;#+/, '');
				group.subtitle = $(this).attr('ows_Subtitle');
				group.minimumDeposit = $(this).attr('ows_MinimumDeposit');
				group.redeemable = $(this).attr('ows_Redeemable') === '1' ? true : false;
				group.fineprint = $(this).attr('ows_Fineprint');
				group.url = $(this).attr('ows_Url');
				group.convertible = $(this).attr('ows_Convertible') === '1' ? true : false;
				groups.push(group);
			});
		}
		return groups;
	};
	var getAll = function (options) {
		var settings = $.extend({
				RateCategoryId: null,
				RateGroupId: null
			}, options || {}),
			query = '',
			i,
			rates = [],
			q = '',
			rows$;

		if (typeof settings.RateCategoryId === 'number') {
			settings.RateCategoryId = [settings.RateCategoryId];				
		}
		if (typeof settings.RateGroupId === 'number') {
			settings.RateGroupId = [settings.RateGroupId];
		}
		
		if (!(settings.RateCategoryId instanceof Array)) {
			settings.RateCategoryId = [];
		}
		if (!(settings.RateGroupId instanceof Array)) {
			settings.RateGroupId = [];
		}
	
		if (settings.RateCategoryId.length > 0 || settings.RateGroupId.length > 0) {
			query = '<Query>';
			query += '<Where>';
			if (settings.RateCategoryId.length > 0 && settings.RateGroupId.length > 0) {
				query += '<And>';
			}
			if (settings.RateCategoryId.length > 0) {
				query += '<In>';
				query += '<FieldRef Name="Category" LookupId="TRUE"/><Values>';
				for (i = 0; i < settings.RateCategoryId.length; ++i) {
					query += '<Value Type="Lookup">' + settings.RateCategoryId[i] + '</Value>';
				}
				query += '</Values></In>';
			}
			if (settings.RateGroupId.length > 0) {
				query += '<In>';
				query += '<FieldRef Name="ID" /><Values>';
				for (i = 0; i < settings.RateGroupId.length; ++i) {
					query += '<Value Type="Number">' + settings.RateGroupId[i] + '</Value>';
				}
				query += '</Values></In>';
			}	
			if (settings.RateCategoryId > 0 && settings.RateGroupId > 0) {
				query += '</And>';
			}
			query += '</Where>';
			query += '</Query>';
		}			
		rows$ = SoapEnvelope.getRows(
			'GetListItems', 
			{ 
				listName: 'RateGroups', 
				rowLimit: 0,
				query: query					
			}
		);
		if(typeof rows$ !== 'undefined') {
		    for (i = 0; i < rows$.length - 1; ++i) {
				q += '<Or>';
			}
			rows$.each(function (index, value) {
				q += '<Eq><FieldRef Name="Group"  LookupId="TRUE"/><Value Type="Lookup">' + $(this).attr('ows_ID') + '</Value></Eq>';
				if (index > 0) {
					q += '</Or>';
				}
			});
		}
		if (q && q.length > 0) {
			rows$ = SoapEnvelope.getRows('GetListItems', { 
				listName: 'Rates', 
				rowLimit: 0,
				query: '<Query><Where>' + q + '</Where></Query>'
			});
			if (typeof rows$ !== 'undefined' && rows$.length > 0) {
				rows$.each(function () {
					var rate = {};
					rate.ID = $(this).attr('ows_ID');
					rate.Title = $(this).attr('ows_Title');
					rate.GroupID = +$(this).attr('ows_Group').match(/^\d+/);
					rate.Group = $(this).attr('ows_Group').replace(/^\d+;#+/, '');
					rate.Rate = $(this).attr('ows_Rate');
					rate.RateNumber = parseFloat($(this).attr('ows_Rate').match(/[\d.]+/));
					rate.RateString = $(this).attr('ows_Rate').match(/[\d.%]+/);
					rate.FeaturedRate = $(this).attr('ows_FeaturedRate');
					rate.BestRate = ($(this).attr('ows_FeaturedRate') || $(this).attr('ows_Rate')).match(/[\d.]+/);
					rate.SplashFeatured = $(this).attr('ows_SplashFeatured');
					rate.Comparables = ['RBC', 'CIBC', 'TD', 'Scotiabank', 'BMO'];
					rate.RBC = $(this).attr('ows_RBC');
					rate.CIBC = $(this).attr('ows_CIBC');
					rate.TD = $(this).attr('ows_TD');
					rate.Scotiabank = $(this).attr('ows_Scotiabank');
					rate.BMO = $(this).attr('ows_BMO');
					rate.VariableRate = $(this).attr('ows_VariableRate') === '1' ? true : false;
					rates.push(rate);
				});
			}
		}
		return rates;
	 },
	 getAllMortgageRates = function () {
		return getAll({ RateCategoryId: 2 });
	 };
		 
	 return { 
		getAll: getAll,
		getAllMortgageRates: getAllMortgageRates,
		getCategories: getCategories,
		getGroups: getGroups 
	 };
}());



















/*

Copyright (c) 2009 Dimas Begunoff, http://www.farinspace.com

Licensed under the MIT license
http://en.wikipedia.org/wiki/MIT_License

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/

;(function($){

	var scrollbarWidth = 0;

	// http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
	function getScrollbarWidth() 
	{
		if (scrollbarWidth) return scrollbarWidth;
		var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div></div>'); 
		$('body').append(div); 
		var w1 = $('div', div).innerWidth(); 
		div.css('overflow-y', 'auto'); 
		var w2 = $('div', div).innerWidth(); 
		$(div).remove(); 
		scrollbarWidth = (w1 - w2);
		return scrollbarWidth;
	}
	
	$.fn.tableScroll = function(options)
	{
		if (options == 'undo')
		{
			var container = $(this).parent().parent();
			if (container.hasClass('tablescroll_wrapper')) 
			{
				container.find('.tablescroll_head thead').prependTo(this);
				container.find('.tablescroll_foot tfoot').appendTo(this);
				container.before(this);
				container.empty();
			}
			return;
		}

		var settings = $.extend({},$.fn.tableScroll.defaults,options);
		
		// Bail out if there's no vertical overflow
		if ($(this).height() <= settings.height)
		{
		  return this;
		}

		settings.scrollbarWidth = getScrollbarWidth();

		this.each(function()
		{
			var flush = settings.flush;
			
			var tb = $(this).addClass('tablescroll_body');

			var wrapper = $('<div class="tablescroll_wrapper"></div>').insertBefore(tb).append(tb);

			// check for a predefined container
			if (!wrapper.parent('div').hasClass(settings.containerClass))
			{
				$('<div></div>').addClass(settings.containerClass).insertBefore(wrapper).append(wrapper);
			}

			var width = settings.width ? settings.width : tb.outerWidth();

			wrapper.css
			({
				'width': width+'px',
				'height': settings.height+'px',
				'overflow': 'auto'
			});

			tb.css('width',width+'px');

			// with border difference
			var wrapper_width = wrapper.outerWidth();
			var diff = wrapper_width-width;

			// assume table will scroll
			wrapper.css({width:((width-diff)+settings.scrollbarWidth)+'px'});
			tb.css('width',(width-diff)+'px');

			if (tb.outerHeight() <= settings.height)
			{
				wrapper.css({height:'auto',width:(width-diff)+'px'});
				flush = false;
			}

			// using wrap does not put wrapper in the DOM right 
			// away making it unavailable for use during runtime
			// tb.wrap(wrapper);

			// possible speed enhancements
			var has_thead = $('thead',tb).length ? true : false ;
			var has_tfoot = $('tfoot',tb).length ? true : false ;
			var thead_tr_first = $('thead tr:first',tb);
			var tbody_tr_first = $('tbody tr:first',tb);
			var tfoot_tr_first = $('tfoot tr:first',tb);

			// remember width of last cell
			var w = 0;

			$('th, td',thead_tr_first).each(function(i)
			{
				w = $(this).width();

				$('th:eq('+i+'), td:eq('+i+')',thead_tr_first).css('width',w+'px');
				$('th:eq('+i+'), td:eq('+i+')',tbody_tr_first).css('width',w+'px');
				if (has_tfoot) $('th:eq('+i+'), td:eq('+i+')',tfoot_tr_first).css('width',w+'px');
			});

			if (has_thead) 
			{
				var tbh = $('<table class="tablescroll_head" cellspacing="0"></table>').insertBefore(wrapper).prepend($('thead',tb));
			}

			if (has_tfoot) 
			{
				var tbf = $('<table class="tablescroll_foot" cellspacing="0"></table>').insertAfter(wrapper).prepend($('tfoot',tb));
			}

			if (tbh != undefined)
			{
				tbh.css('width',width+'px');
				
				if (flush)
				{
					$('tr:first th:last, tr:first td:last',tbh).css('width',(w+settings.scrollbarWidth)+'px');
					tbh.css('width',wrapper.outerWidth() + 'px');
				}
			}

			if (tbf != undefined)
			{
				tbf.css('width',width+'px');

				if (flush)
				{
					$('tr:first th:last, tr:first td:last',tbf).css('width',(w+settings.scrollbarWidth)+'px');
					tbf.css('width',wrapper.outerWidth() + 'px');
				}
			}
		});

		return this;
	};

	// public
	$.fn.tableScroll.defaults =
	{
		flush: true, // makes the last thead and tbody column flush with the scrollbar
		width: null, // width of the table (head, body and foot), null defaults to the tables natural width
		height: 100, // height of the scrollable area
		containerClass: 'tablescroll' // the plugin wraps the table in a div with this css class
	};

})(jQuery);
