try{
document.domain = "mindbloom.com";
} catch (err) {}

var mb_util = {};

mb_util.mb_user = null;
mb_util.mb_user_tree = null;
mb_util.session_id = null;

// Realized leaf_template data is a fairly commonly used data. When it's loaded, let's save and use later without loading again.
mb_util.tree_template = null; 
mb_util.debug_mode = false;

mb_util.min_age = 13;
mb_util.errors = {
    'invalid_age':"Sorry, you must be at least 13 years old to grow the life you want.",
    'invalid_year':"Please enter a year after 1901.",
    'invalid_date':"Invalid date format.  Must use MM/DD/YYYY.",
    'invalid_day':"Day of month is out of range.",
    'invalid_month':"Month of year is out of range"
};

mb_util.tool_tips = {
    'comment_flag':"Flag or block",
    'comment_remove':"Remove comment",
    'comment_add':"Add comment",
    'action_add':"Add actions",
    'privacy':"Set privacy",
    'action_change':" (Click to change)",
    'action_changejournal':" (Click to change or journal)",
    'action_uncommitted':"Click to schedule",
    'action_committed':"Click to unschedule",
    'action_completed':"I did it!",
	'action_iRock':"I Rock!",
	'action_yay':"Yay!",
	'action_oops':"Oops!",
	'action_no':"No!",
    'action_today':"Click if you did it",
    'action_missed':"I missed it",
    'action_delete':"Delete or stop doing this action",
    'action_drag':"Drag and drop",
    'action_restart':"Restart action",
    'action_remove':"Delete action",
    'insp_remove':"Remove inspiration",
    'insp_lifearea':"Life Area",
    'insp_privacy':"Who can see this?",
    'insp_view':"Show posts...",
    'friend_add':"Add friends",
    'friend_remove':"Remove friend",
    'friend_addgroup':"Add friend to group(s)",
    'friend_removegroup':"Remove group",
    'friend_addremove':"Add & remove friends from group",
    'market_actions':"Do this!",
    'market_images':"Add to my inspiration" 
};

mb_util.emoticon_image_files = {
    0:"/icons/large/001_06.png",
    1:"/icons/large/001_15.png",
    2:"/emoticons/icontexto-emoticons-01-032x032.png",
    3:"/emoticons/icontexto-emoticons-02-032x032.png",
    4:"/emoticons/icontexto-emoticons-04-032x032.png",
    5:"/emoticons/icontexto-emoticons-09-032x032.png",
    6:"/emoticons/icontexto-emoticons-12-032x032.png",
    7:"/emoticons/icontexto-emoticons-13-032x032.png"
};

mb_util.SUPPORT_PAGE_URL = 'http://www.mindbloom.com/the-company/support/';

// Use this function as a parameter for the list sorting function ( .sort() ) to randomly sort the list.
mb_util.randomSortingFunction = function(){return 0.5 - Math.random()};

// IE 7/8 Does not have Array.indexOf so just implement it...
if (!Array.prototype.indexOf){
	Array.prototype.indexOf = function(obj, start) {     
		for (var i = (start || 0), j = this.length; i < j; i++) {         
			if (this[i] === obj) { return i; }    
		}     
		return -1;
	}
}

mb_util.logToConsole = function(msg){
	try {
		if(console && console.log)
		{
			if(console.groupCollapsed)
			{
				console.groupCollapsed("Javascript: " + msg);
				console.trace();
				console.groupEnd();
			}
			else
			{
				console.log("Javascript: " + msg);
			}
		}
	} catch (err) {}
}

mb_util.loadUser = function(callback){
	$.ajax({
		url:'/session/mb_user_session',
		type:'GET',
		dataType:'json',
		success:function(data){
			mb_util.mb_user = data.user;
			mb_util.session_id = data.session_id;
			if(callback){
				callback(data);
			}
		}
	});
}

mb_util.loadTree = function(callback){
	$.ajax({
		url:'/api/tree/'+mb_util.mb_user.id,
		data:'GET',
		dataType:'json',
		success:function(data){
			mb_util.mb_user_tree = data;
			if(callback){
				callback();
			}
		}
	});
}

mb_util.updateUser = function(args,callback){
	$.ajax({
		url: "/api/mb_user/me",
		type: "PUT",
		dataType: "json",
		data: (args),
		success:function(data){
			mb_util.mb_user = data;
			if(callback){
				callback()
			}
		}
	});
	
}

mb_util.blackoutOpen = function(clickCallback){
	$('.blackout').remove();
	var blackoutDiv = $("<div/>")
		.attr("class", 'blackout')
		.appendTo('body');

	blackoutDiv.delay(300).fadeIn("slow")
		.css('opacity', 0.6); // Hack for IE
	
	if(clickCallback) {
		blackoutDiv.bind("click", clickCallback);
	}
};

mb_util.blackoutClose = function(){
	$(".blackout").fadeOut("fast");
}

mb_util.closeAlertBox = function(instant){
	mb_util.blackoutClose();
	if(instant){
		$("#alertBox").remove();
		return false;
	}
	$("#alertBox").fadeOut("fast", 
		function (){$("#alertBox").remove();}
	);
	return false;
}

// Params:
//  cssClass: 
//      null | "error" | "prompt" | "success"
//  icon:
//      null | "seeds" | "done" | "question" | "comment" | "add" | "delete" |
//      "waiting" | "password" | "friends" | "email" | "locked"
mb_util.alertBox = function(cssClass,icon,title,subtitle,body,buttons,isModal,closeCallback,notification){
	$("#alertBox").remove();
	if (isModal){
		mb_util.blackoutOpen(null);
	} else if(notification){
		//do nothing
	} else if (!closeCallback){
		mb_util.blackoutOpen(mb_util.closeAlertBox);
	}
	else {
		mb_util.blackoutOpen(closeCallback);
	}
	return mb_util.alertBoxDraw(cssClass,icon,title,subtitle,body,buttons,isModal,notification);
}
mb_util.alertBoxDraw = function(cssClass,icon,title,subtitle,body,buttons,isModal,notification){
	$("#alertBox").remove();
	var alertBoxContent = $("<div/>")
	.attr("class", "content")
	.append(
		$("<div/>").attr('class','icon')
	)
	.append(
		$("<h2/>").html(title)
	);

	if(subtitle){
		alertBoxContent.append($("<h3/>").html(subtitle));
	}
	if(body){
		alertBoxContent.append(
			$("<div/>").attr("class", "body").html(body)
		);
	}

	var alertBoxDiv = $("<div/>")
	.attr("id", "alertBox")
	.append(alertBoxContent);
	if(cssClass){
		alertBoxDiv.addClass(cssClass);
	}
	if(icon){
		alertBoxDiv.addClass(icon);
	}

	if(buttons && buttons.length>0){
		alertBoxDiv.append('<hr/>');
		var buttonDiv = $("<div/>").attr("class", "buttons").hide();
		for (b in buttons){
			button = buttons[b];
			if(button[0] && button[0]!="_"){
				buttonDiv.append($("<button/>")
					.attr('id','button_'+[b])
					.attr("class", "button " + button[1] + " " + button[2])
					.bind("click",{callback:button[3]},function(e){
						e.data.callback();
						return false;
					})
					.html(button[0])
				);
			}
		}
		alertBoxDiv.append(buttonDiv);
	}
	
	if(!isModal){
		var closeButton = $("<a/>")
			.addClass("closeButton")
			.bind("click",mb_util.closeAlertBox);
		alertBoxDiv.append(closeButton);
		if(notification){
			closeButton.hide();
			alertBoxDiv.hover(function(){
				closeButton.fadeIn();
			},function(){
				closeButton.fadeOut();
			});
		}
	}

	$("body").append(alertBoxDiv);
	alertBoxDiv.css("overflow", "visible");
	alertBoxDiv.animate(
		{marginLeft: "-205px", marginTop: "-85px", opacity:1}, 
		300,"swing", 
		function() {
			$('#alertBox').css('filter','');
			alertBoxDiv.css("overflow", "visible");
		}
	);
	$('#alertBox .buttons').fadeIn();
	return alertBoxDiv;
}

// A simple alert box that only has a close button
mb_util.simpleAlertBox = function(str,cssClass,isModal,icon){
	var heading = null;
	var subheading = null;
	var body = null;
	if(str.length<150){
		heading = str;
	} else if(str.length<250) {
		subheading = str;
	} else {
		body = str;
	} 
	var buttons = (isModal) 
	? []
	: [["OK","black","medium",mb_util.closeAlertBox]];
	return mb_util.alertBox(
		cssClass,icon,heading,subheading,body,buttons,isModal
	);
}

// An alert box with a Yes and No Button
mb_util.confirmAlertBox = function(str,yesColor,yesCallback,cssClass){
	var heading = null;
	var subheading = null;
	var body = null;
	if(str.length<150){
		heading = str;
	} else if(str.length<250) {
		subheading = str;
	} else {
		body = str;
	} 
	return mb_util.alertBox(
		cssClass,'question',heading,subheading,body,
		[
		["No","black","medium",mb_util.closeAlertBox],
		["Yes",yesColor,"medium",yesCallback],
		]
		,false
	);
}

mb_util.showTipThread = null;

mb_util.showTip = function(me, msg, head, key, parent, cssClass){
	return mb_util.toolTip(me, msg, head, key, parent, true, cssClass);
};

mb_util.notificationBox = function(str,cssClass,icon){
	var heading = null;
	var subheading = null;
	var body = null;
	if(str.length<150){
		heading = str;
	} else if(str.length<250) {
		subheading = str;
	} else {
		body = str;
	} 
	cssClass += ' notification';
	var box = mb_util.alertBox(
		cssClass,icon,heading,subheading,body,[],false,null,true
	).bind('click',function(){
		box.fadeOut(function(){$(this).remove()});
	});
	setTimeout(function(){
		box.fadeOut(function(){$(this).remove()});
	},5000);
	return box;
};

mb_util.currentLockedTipKey = []; // Mechanism to prevent some tool tips to appear.

// me is either a dom object or an array with this format = [left, top, width, height]
mb_util.toolTip = function(me, msg, head, key, parent, is_hover, cssClass){
	var bubble, offset, width, height, m_width, m_height, left, top;
	
	if(is_hover&&mb_common_client.isTouchscreen()){
		return false;
	}
	
	//mb_util.logToConsole("currentLockedTipKey = " + mb_util.currentLockedTipKey  + " key passed is " + key );
	if (key && mb_util.currentLockedTipKey.indexOf(key) >= 0) {return;} // Don't open if the key is one of the locked ones

	if(is_hover){
		mb_util.closeShowTip(true);    	
	} else {
	    mb_util.closeToolTip(true);
	}
	
	//var currentToolTip = $('.toolTip');
	//if (currentToolTip && currentToolTip.data('key') == key && is_hover) return; // If there is already a tool tip open for the same element, skip.
	
	key = key || '';
	
	parent = parent || $('body');
	
	bubble = $('<div/>')
		.attr('class','toolTip')
		.addClass(is_hover?'showTip':'staticTip')
		.append(
			$('<div/>')
				.attr('class','arrow')
		)
		.append(
			(head)? 
			$('<div/>')
				.attr('class','head')
				.html(head)
			: ''
		)
		.append(
			$('<div/>')
				.attr('class','message')
				.html(msg)
		)
		.appendTo(parent)
		.data('key', key) // store the key. used in some cases
		.addClass(key)
		.hide();
	if(cssClass){
	    if(cssClass=='center'){bubble.find('.message').addClass(cssClass);}
	    else{bubble.addClass(cssClass);}
	}
	
	if(is_hover){
		bubble.css({'pointer-events':'none'});
	}

	width = bubble.width();
	height = bubble.height();

	if(me instanceof Array){
		offset = {left:me[0], top:me[1]};
		m_width = me[2];
		m_height = me[3];
		
	} else{
		offset = $(me).offset();
		m_width = $(me).width();
		m_height = $(me).height();
	}
	
	left = offset.left - (width/2) + (m_width / 2);
		
	top = offset.top - height - 20;
	
	// Spacial adjustment
	
	if( top < 0 ){
		top = offset.top + m_height + 20;
		bubble.addClass('up');
	}
	if( $(window).width() - left < width ) {
		left -= width/2 - 23;
		bubble.addClass('right');
	}
	if( left < 0 ) {
		left += width/2 - 28;
		bubble.addClass('left');
	}
	
	bubble.css({left: left, top: top});
	
	if(is_hover){
		mb_util.showTipThread = setTimeout(function(){
			bubble.fadeIn();
			mb_util.showTipThread = null;
		}, 750);
	} else{
		bubble.fadeIn();
	}
	
	setTimeout(function(){
		if (is_hover){
			if(!(me instanceof Array)){
				$(me).bind('mouseout', function(){
				    $(this).unbind('mouseout'); // Prevents infinite binding
					if (mb_util.showTipThread){
						clearTimeout(mb_util.showTipThread);
						mb_util.showTipThread = null;
					} else {
						mb_util.closeShowTip();
					}
				});
			}
		} else {
			//hack
			if(bubble.attr('id')=='seedProgress'){
				return;
			}
			bubble.bind('clickoutside', function(){
                $(this).unbind('clickoutside');
			    mb_util.closeToolTip();
			});
		}
	},10);
	return bubble;
}

mb_util.closeShowTip = function(instant){
	$('.showTip').remove();
	return false;
}

mb_util.closeToolTip = function(instant,hardClose){
    var toolTip = $('.staticTip');
	if (toolTip.hasClass('bigLock')&& !hardClose) { return; }
    toolTip.unbind();
	if (instant) {
		toolTip.remove();
	} else  {
		toolTip.stop().fadeOut();
	}
	return false;
}



mb_util.decodeString = function(str, linebreak){   
	if(str === null){return null;}
	return (linebreak)?
	$.trim(str.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&#39;&#39;/g, "\"").replace(/&#39;/g, "'").replace(/\&amp;/g,'&').replace(/\n/g, "<br />").replace(/\n\n+/g, '<br /><br />').replace(/(\<\/?)script/g,"$1noscript"))
	:$.trim(str.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&#39;&#39;/g, "\"").replace(/&#39;/g, "'").replace(/\&amp;/g,'&'));
}

mb_util.truncate = function(str, l){
	if (!str) {return '';}
	if (str.length <= l) return str;
	var str2 = str.substr(0, (l-3));
	str2 += '...';
	return str2;
}

mb_util.isValidEmail = function(email){
    var emailRegExS = /^[a-zA-Z0-9\+.-_]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
    var emailRegEx = new RegExp(emailRegExS);
    return (emailRegEx.test(email));
}

mb_util.compareArrays = function(x, y){
	if(x===null&&y===null){
		return true;
	}
	if(x===null||y===null){
		return false;
	}
	if(x.length!=y.length){
		return false;
	}
	for(var propertyName in x) {
		if(x[propertyName] !== y[propertyName]) {
			return false;
		}
	}
	return true;
}

mb_util.getParentTemplateId = function(leaf_template_id){
	if(!mb_util.tree_template){
		$.getJSON('/api/tree_template',function(data){
			mb_util.tree_template = data;
		});
		return false;
	}
	var result = false;
	$.each(mb_util.tree_template,function(t,tree){
		$.each(tree.children,function(l,leaf_template){
			if(leaf_template_id==leaf_template.id){
				result = tree.id;
				return false;
			} else {
				$.each(leaf_template.children,function(c,child_template){
					if(leaf_template_id==child_template.id){
						result = leaf_template.id;
						return false;
					}
				});
				if(result){
					return false;
				}
			}
		});
	});
	return result;
};


mb_util.getTemplateName = function(leaf_template_id,sub){
	if(!mb_util.tree_template){
		$.getJSON('/api/tree_template',function(data){
			mb_util.tree_template = data;
		});
		return '';
	}
	var result = '';
	$.each(mb_util.tree_template,function(t,tree){
		$.each(tree.children,function(l,leaf_template){
			if(leaf_template_id==leaf_template.id){
				result = leaf_template.name;
				return false;
			} else {
				$.each(leaf_template.children,function(c,child_template){
					if(leaf_template_id==child_template.id){
						if(sub){
							result = child_template.name;
						} else{
							result = leaf_template.name;
						}
						return false;
					}
				});
				if(result){
					return false;
				}
			}
		});
	});
	return result;
};

mb_util.getParameterByName = function( name , url ){
	url = url || window.location.href;
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+name+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec( url );
	if( results == null )
	return "";
	else
	return decodeURIComponent(results[1].replace(/\+/g, " "));
};

// Takes a string form of the date we get from the server (e.g. media_image.created_date)
// and returns a javascript date object. Doing something like new Date(media_image.created_date)
// only works in firefox. Use this function instead.
mb_util.parseJSONDate = function(str){
	var dateData = str.split('-');
	var Year = dateData[0];
	var Month = dateData[1];
	var dateData_2 = dateData[2].split("T");
	var Day = dateData_2[0];
	var timeData = dateData_2[1].split(":");
	var Hour = timeData[0];
	var Minute = timeData[1];
	var Second = parseInt(timeData[2], 10) | 0;
	return new Date(Year, (parseInt(Month, 10)-1), Day, Hour, Minute, Second, 0);
};

// Utility used in some apps. It gives you the key from a value.
mb_util.invDict = function(dict, value){
		if(dict === null){return null;}
		var match=null;
		$.each(dict, function(k,v){		
			if (v==String(value)){
				match = k; 
				return false;//same as break
			}
		});
		return match;
};

// Convert yyyy-mm-dd string to english, readable date
mb_util.formatDate = function(date,us) {
    if(us){
        return date.substring(5,7)+'/'+date.substring(8)+'/'+date.substring(0,4);
    }
    
	var today = new Date();
	today.setMinutes(0);
	today.setMinutes(0);
	var yesterday = new Date();
	yesterday.setDate(today.getDate()-1);
	var date_vals = date.split('-');
	var my_date = new Date();
	my_date.setFullYear(date_vals[0], date_vals[1] - 1, date_vals[2], 0, 0, 0);
	if(my_date.getFullYear() == today.getFullYear() && 
		my_date.getDate() == today.getDate() && 
		my_date.getMonth() == today.getMonth() ){
		return 'Today';
	}
	else if(my_date.getFullYear() == today.getFullYear() && 
		my_date.getDate() == today.getDate() - 1 && 
		my_date.getMonth() == today.getMonth() ){
		return 'Yesterday';
	}
	else{
		return my_date.toDateString();
	}
};

mb_util.isValidPass = function(pass){
    var res = /^[\w\d~!@#$%^&*()_+<>`,.?\\/]+$/;
    var re = new RegExp(res);
    return re.test(pass);
};

mb_util.isValidDate = function(date,error_string) {
    function returnError(err){
        if (error_string) error_string.value = mb_util.errors[err];
        return false;
    }
    
    var dateObj = new Date();
    var yearMin = 1900;
    var yearMax = dateObj.getFullYear()-mb_util.min_age;
    var dateRegExS = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
    var dateRegEx = new RegExp(dateRegExS);
    if (!dateRegEx.test(date))
        return returnError('invalid_date');

    // check ranges
	var date_array = date.split('/');
	var month = date_array[0]-1, day = date_array[1], year = date_array[2];
    
    if (month > 11 || month < 0)
        return returnError('invalid_month');
    switch(month){
    case 0: case 2: case 4: case 6: case 7: case 9: case 11:
        if(!(day > 0 && day <=31))
            return returnError('invalid_day');
        break;
    case 3: case 5: case 8: case 10:
        if(!(day > 0 && day <=30))
            return returnError('invalid_day');
        break;
    default:
        if( !(day > 0 && day <=29) )
            return returnError('invalid_day');
    }
    
    if (!(year > yearMin))
        return returnError('invalid_year');
    else if (!(year<=yearMax))
        return returnError('invalid_age');
    else if (year == yearMax)
        if (month > dateObj.getMonth())
            return returnError('invalid_age');
        else if (month == dateObj.getMonth() && day > dateObj.getDate())
            return returnError('invalid_age');
    return true;
};

mb_util.isValidStrictPassword = function(pw){
	// strict password means at least 8 characters alphanumaric + special character
	var re = /^.*(?=.{8,})(?=.*\d)(?=\w*[a-zA-Z])(?=.*[!@#$%^&+=\-_\?]).*$/;
	return re.test(pw);
};

mb_util.strip = function(html){
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent||tmp.innerText;
};


// Convert gender to his, her, or their
mb_util.possessiveAdjective = function(gender) {
	switch (gender) {
		case 0:
			return "his";
		case 1:
			return "her";
		default:
	        return "their";
	}
};

mb_util.signout = function(redirect_url){
	$.getJSON("/session/logout",function(data){
		window.location = redirect_url?(redirect_url):'http://' + window.location.host;
	});
};

mb_util.hasUrl = function(string){
	var e = /(((http|https):\/\/)([0-Z]|.|\/)*|(www.)([0-Z])*(.)([0-Z]|.|\/)*)/;
	return e.exec(string);
};

mb_util.renderDateDropdown = function(year, month, day, what){
	var div = $('<span/>').addClass('dateDropdown')
		// Very strange bug in IE8. The first select element is not selectable by mouse. The options hide immediate when hovered over.
		// Adding a hidden select element to fix.
		.append( mb_common_client.isIELegacy()? $('<select/>').css("display", "none"):'')
		.append( $('<select/>')
			.attr('id', month)
		)
		.append( $('<select/>')
			.attr('id', day)
		)
		.append( $('<select/>')
			.attr('id', year)
		);
	var today = new Date();
	
	var monthMap = {
		1: "Jan",
		2: "Feb",
		3: "Mar",
		4: "Apr",
		5: "May",
		6: "Jun",
		7: "Jul",
		8: "Aug",
		9: "Sep",
		10: "Oct",
		11: "Nov",
		12: "Dec"
	};
	
	for(var i = today.getFullYear(); i>1900;i--){
	    var opt = $('<option/>').attr('value',i).html(i);
		$('#'+year, div).append(opt);
	}
	for(var i = 1; i<13;i++){
		$('#'+month, div).append('<option value="'+i+'">'+monthMap[i]+'</option>');
	}
	what.append(div);
	$.dateSelectBoxes(month, day, year);
};

mb_util.isSmallScreen = function(){
	return $(window).height() < 720; // 720 pixel height is the break point where the tree starts to look too big.
};

mb_util.flashErrorMessage = function(text){
	text = text || 'You need to have the latest version of Flash installed to upload images and music.';
	mb_util.alertBox(
		null,"warning",'Flash Required', text
		, 
		'<div style="margin-top:15px;"><a href="http://get.adobe.com/flashplayer/" target="_blank" style="color:white;text-decoration:underline;">Get Flash Now</a></div>',
		[
			[
				"Close","black","wide",mb_util.closeAlertBox
			]
		],
		true
	);
};

mb_util.rand = function(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
};

mb_util.findLeaf = function(leaf_id){
	var leaf = null;
	$.each(mb_util.mb_user_tree[mb_util.mb_user.default_tree_id].children, function(i, branch){
		if (branch.id == leaf_id){
			leaf = branch;
			return false;
		}
		$.each(branch.children, function(k, subleaf){
			if(subleaf.id == leaf_id){
				leaf = subleaf;
				return false;
			}
		});
	});
	return leaf;
};

mb_util.findLeafWithLeafTemplateId = function(leaf_template_id){
	var leaf = null;
	$.each(mb_util.mb_user_tree[mb_util.mb_user.default_tree_id].children, function(i, branch){
		if (branch.leaf_template_id == leaf_template_id){
			leaf = branch;
			return false;
		}
		$.each(branch.children, function(k, subleaf){
			if(subleaf.leaf_template_id == leaf_template_id){
				leaf = subleaf;
				return false;
			}
		});
	});
	return leaf;
};

mb_util.findLeafTemplate = function(leaf_template_id){
	var leaf_template;
	$.each(mb_util.tree_template, function(life_leaf_id, life_leaf){
		if(life_leaf.id == leaf_template_id){
			leaf_template = life_leaf;
			return false;
		}
		$.each(life_leaf.children, function(i, branch){
			if (leaf_template){
				return false;
			}
			if(branch.id == leaf_template_id){
				leaf_template = branch;
				return false;
			}
			$.each(branch.children, function(j, leaf){
				if(leaf.id == leaf_template_id){
					leaf_template = leaf;
					return false;
				}
			});
		});
	});
	
	return leaf_template;
};

mb_util.isScrolledIntoView = function(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}

mb_util.counter = function(dom,delta,target,duration,onComplete){
	mb_util._counter_dom = $(dom);
	mb_util._counter_start = parseInt($(dom).html()) || 0;
	if (target){
		mb_util._counter_final = target;
	} else {
		mb_util._counter_final = mb_util._counter_start+delta;
	}
	var a = new Animator({
		duration:duration||1500,
		onComplete:onComplete
	});
	a.addSubject(mb_util._counter);
	a.toggle();
};

mb_util._counter = function(value){
	if (!mb_util._counter_dom){ return; }
	mb_util._counter_dom.html(parseInt((mb_util._counter_final-mb_util._counter_start)*value)+mb_util._counter_start);
};

mb_util.html_encode = function(value){
  return $('<div/>').text(value).html();
};

mb_util.html_decode = function(value){
  return $('<div/>').html(value).text();
};

mb_util.nophoto = function(size){
	size = size || 'icon';
	return '/media/img/common/icon/picframe_nophoto_'+size+'.png';
};
mb_util.nophotoFull = function(size){
	return 'http://'+window.location.host+mb_util.nophoto(size);
};
