/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};;(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return date.getUTCFullYear()+'-'+
toIntegersAtLease(date.getUTCMonth()+1)+'-'+
toIntegersAtLease(date.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'}
$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"'}
return'"'+string+'"';}
$.toJSON=function(o)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON();if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i]));}
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
ret=[];for(var k in o){var name;var type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;val=$.toJSON(o[k]);if(typeof(val)!="string"){continue;}
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";}
$.evalJSON=function(src)
{return eval("("+src+")");}
$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");}})(jQuery);;	/*
		PureJSTemplate
		Author: Mohammad S. Rahman
		License: MohammadLicense- use it, but quote me or I'll get you.
		Test: /test/purejstemplatetest.html
		
		Why use this: ITS FAST!!!
	*/
	(function($) {	
	$.fn.pureJSTemplate=function(options) {
		var tplID=options.id;
		if(!tplID)return '';
		tplID=tplID.toString();
		var input= options.data;
		var tpl = '';
		var tplObj;
		if((tplID.indexOf(' ') != -1) || (tplID.indexOf('(') != -1) || (tplID.indexOf('(*') != -1) || !tplMap[tplID] || options.parseText)
		{
			if(tplID.indexOf(' ') == -1 &&  tplID.indexOf('(*') == -1 &&  tplID.indexOf('(') == -1 && !options.parseText)
			{
				tplObj=tplMap[tplID];
				if(!tplObj) {
					var obj = document.getElementById(tplID+'.tpl');
					if(obj)
					{
						tpl = obj.value;
					}
					else
					{
						var fileName = (tplID.indexOf('/layouts/')==-1)?((VHV.path=='/')?'/'+VHV.App.mainPackage+'/':VHV.path)+'layouts/'+VHV.App.layout+'/'+tplID+'.html':VHV.staticURL+tplID+'.html';
						VHV.read(fileName.replace(/\/\//g, '/'),{async:false},
							function(code)
							{
								tpl = code;
							}
						);
					}
				}
			}
			else
			{
				tpl = tplID;
			}
			var leftjs=String.fromCharCode(21);
			var leftjsout=leftjs + "=";
			
			tpl=tpl.replace(replaceLeft, left+leftjs );
			
			var tplSplit = tpl.split(regexLeftRight);
			var js="var data=arguments[0];  var output=''; var ld='"+left+"'; var rd='"+right+"'; ";
			for(var i=0; i<tplSplit.length; i++) {
			
				var line = tplSplit[i];
		
				if(stringStartsWith(line, leftjsout)) {
					js+=" output+=" + line.substring(leftjsout.length) + "; ";
				}
				else if(stringStartsWith(line,leftjs)) {
					js+=" " + line.substring(leftjs.length) + "; ";
				}
				else {
					js+=" output+='" + line.replace(/\\/g, "\\\\").replace(replaceSingleQuote, "\\'").replace(replaceLineBreak, "\\n")+ "'; ";
				}
			}
			
			js+="; return output;";
			//if(window.console) console.log(js);
			tplObj = new Function(js);
			if(tplID.indexOf(' ') == -1 && tplID.indexOf('(*') == -1 && !options.parseText)
			{
				tplMap[tplID]=tplObj;
			}
		}
		else
		{
			tplObj = tplMap[tplID];
		}
		if(this.length)
		{
			this.html(tplObj(input));
			return this;
		}
		else
		{
			return tplObj(input);
		}
	}
	tplMap={};

	var left="<#";
	var right="#>";

	//Delimiters can have regex special characters in them; the following two variables will hold escaped versions of them
	var escapedLeft="<#"; 
	var escapedRight="#>";

	var specials= [ '$','^','?','/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ];
	var escapeRegex	= new RegExp( '(\\' + specials.join('|\\') + ')', 'g');

	var replaceLeft=new RegExp(escapedLeft, "g");
	var regexLeftRight= new RegExp(escapedLeft + "|" + escapedRight, "g");
	
	var replaceSingleQuote=new RegExp("'","g");
	var replaceLineBreak = new RegExp("\\r\\n|\\r|\\n", "g");


	$.fn.pureJSTemplate.setDelimiters=function(l, r) {
		if(l!=r) {
			left=l;
			escapedLeft = left.replace(escapeRegex, '\\$1');	
			replaceLeft=new RegExp(escapedLeft, "g");
		
			right=r;
			escapedRight = right.replace(escapeRegex, '\\$1');	

			regexLeftRight= new RegExp(escapedLeft + "|" + escapedRight, "g");
		}
	}

	function stringStartsWith(str, startsWith) {
		return str.substring(0, startsWith.length)==startsWith;
	}

	})(jQuery);
;

/**
 * This jQuery plugin displays pagination links inside the selected elements.
 *
 * @author Gabriel Birke (birke *at* d-scribe *dot* de)
 * @version 1.1
 * @param {int} maxentries Number of entries to paginate
 * @param {Object} opts Several options (see README for documentation)
 * @return {Object} jQuery Object
 */
jQuery.fn.pagination = function(maxentries, opts){
	opts = jQuery.extend({
		items_per_page:15,
		num_display_entries:8,
		current_page:0,
		num_edge_entries:0,
		link_to:"#",
		prev_text:"<<",
		next_text:">>",
		ellipse_text:"...",
		prev_show_always:true,
		next_show_always:true,
		// Khoanb Edit 24.04.2009
		dis_pageEnd: false,
		start_text:"<<",
		end_text:">>",
		// Khoanb End Edit 24.04.2009
		callback:function(){return false;}
	},opts||{});
	return this.each(function() {
		/**
		 * Calculate the maximum number of pages
		 */
		function numPages() {
			return Math.ceil(maxentries/opts.items_per_page);
		}
		
		/**
		 * Calculate start and end point of pagination links depending on 
		 * current_page and num_display_entries.
		 * @return {Array}
		 */
		function getInterval()  {
			var ne_half = Math.ceil(opts.num_display_entries/2);
			var np = numPages();
			var upper_limit = np-opts.num_display_entries;
			var start = current_page>ne_half?Math.max(Math.min(current_page-ne_half, upper_limit), 0):0;
			var end = current_page>ne_half?Math.min(current_page+ne_half, np):Math.min(opts.num_display_entries, np);
			return [start,end];
		}
		
		/**
		 * This is the event handling function for the pagination links. 
		 * @param {int} page_id The new page number
		 */
		function pageSelected(page_id, evt){
			current_page = page_id;
			drawLinks();
			var continuePropagation = opts.callback(page_id, panel);
			if (!continuePropagation) {
				if (evt.stopPropagation) {
					evt.stopPropagation();
				}
				else {
					evt.cancelBubble = true;
				}
			}
			return continuePropagation;
		}
		
		/**
		 * This function inserts the pagination links into the container element
		 */
		function drawLinks() {
			panel.empty();
			var interval = getInterval();
			var np = numPages();
			// This helper function returns a handler function that calls pageSelected with the right page_id
			var getClickHandler = function(page_id) {
				return function(evt){ return pageSelected(page_id,evt); }
			}
			// Helper function for generating a single link (or a span tag if it'S the current page)
			var appendItem = function(page_id, appendopts){
				page_id = page_id<0?0:(page_id<np?page_id:np-1); // Normalize page id to sane value
				appendopts = jQuery.extend({text:page_id+1, classes:""}, appendopts||{});
				if(page_id == current_page){
					var lnk = $("<span class='current'>"+(appendopts.text)+"</span>");
				}
				else
				{
					var lnk = $("<a>"+(appendopts.text)+"</a>")
						.bind("click", getClickHandler(page_id))
						.attr('href', opts.link_to.replace(/__id__/,page_id));
						
						
				}
				if(appendopts.classes){lnk.addClass(appendopts.classes);}
				panel.append(lnk);
			}
			// Generate "Start Page"- Link
			if(current_page >= 0){
				appendItem(0,{text:opts.start_text?opts.start_text:"&nbsp;", classes:"first"});
			}
			
			// Generate "Previous"-Link
			if(opts.prev_text && (current_page > 0 || opts.prev_show_always)){
				// Khoanb Edit 24.04.2009
				if(opts.dis_pageEnd){
					appendItem(0,{text:opts.start_text, classes:"prev"});
				}
				// Khoanb End Edit 24.04.2009
				appendItem(current_page-1,{text:opts.prev_text, classes:"prev"});				
			}
			// Generate starting points
			if (interval[0] > 0 && opts.num_edge_entries > 0)
			{
				var end = Math.min(opts.num_edge_entries, interval[0]);
				for(var i=0; i<end; i++) {
					appendItem(i);
				}
				if(opts.num_edge_entries < interval[0] && opts.ellipse_text)
				{
					jQuery("<span>"+opts.ellipse_text+"</span>").appendTo(panel);
				}
			}
			// Generate interval links
			for(var i=interval[0]; i<interval[1]; i++) {
				appendItem(i);
			}
			// Generate ending points
			if (interval[1] < np && opts.num_edge_entries > 0)
			{
				if(np-opts.num_edge_entries > interval[1]&& opts.ellipse_text)
				{
					jQuery("<span>"+opts.ellipse_text+"</span>").appendTo(panel);
				}
				var begin = Math.max(np-opts.num_edge_entries, interval[1]);
				for(var i=begin; i<np; i++) {
					appendItem(i);
				}
				
			}
			// Generate "Next"-Link
			if(opts.next_text && (current_page < np-1 || opts.next_show_always)){
				appendItem(current_page+1,{text:opts.next_text, classes:"next"});
				// Khoanb Edit 24.04.2009
				if(opts.dis_pageEnd){
					appendItem(np,{text:opts.end_text, classes:"next"});
				}
				// Khoanb End Edit 24.04.2009
			}
			
			// Generate "End"-Link
			if(np>=1){
				appendItem(end,{text:opts.end_text?opts.end_text:"&nbsp;", classes:"last"});
			}
		}
		
		// Extract current_page from options
		var current_page = opts.current_page;
		// Create a sane value for maxentries and items_per_page
		maxentries = (!maxentries || maxentries < 0)?1:maxentries;
		opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0)?1:opts.items_per_page;
		// Store DOM element for easy access from all inner functions
		var panel = jQuery(this);
		// Attach control functions to the DOM element 
		this.selectPage = function(page_id){ pageSelected(page_id);}
		this.prevPage = function(){ 
			if (current_page > 0) {
				pageSelected(current_page - 1);
				return true;
			}
			else {
				return false;
			}
		}
		this.nextPage = function(){ 
			if(current_page < numPages()-1) {
				pageSelected(current_page+1);
				return true;
			}
			else {
				return false;
			}
		}
		// When all initialisation is done, draw the links
		drawLinks();
	});
};$.browser.ie6 = $.browser.msie && (parseInt($.browser.version) < 7);
ReadyObject = {
	isReady: false,
	init:function()
	{
		this.isReady = true;
	},
	ready:function(func)
	{
		VHV.ExecQueue.add(func, function(){return this.isReady;}, this);
	}
};
VHV = $.extend({
	cache:{},
	debug:1,
	frameworkCache:false,
	publishModules:false,
	publish:false,
	noGroupService:true,
	publishPages:false,
	async:true,
	allLinks:{},
	xmlCache:{},
	domain:location.host,
	home: 'http://'+location.host,
	version:1.21,
	rootURL:'/',
	staticURL:'',
	innerText:$.browser.msie?($.browser.ie6?'nodeValue':'innerText'):'textContent',
	allOrderedLinks:[],
	template: function(id, data, parseText)
	{
		return $.fn.pureJSTemplate({
			id:id, 
			data:data,
			parseText:parseText
		});
	},
	request: function(param, defaultValue) {
		if(typeof(defaultValue) == 'undefined')
		{
			defaultValue = '';
		}
		var regex = '[?&]' + param + '=([^&#]*)';
		var results = (new RegExp(regex)).exec(VHV.location?VHV.location:location.href);
		if(results)
		{
			return decodeURIComponent(results[1]);
		}
		else
		{
			var regex = '[?&]'+param+'\\[(\\w*)\\]=([^&#]*)', regExpObj = new RegExp(regex, 'g');
			var matches = location.href.toString().replace(/\%5B/g, '[').replace(/\%5D/g, ']').match(regExpObj);
			if(matches)
			{
				var items = {};
				for(var i = 0; i < matches.length; i++)
				{
					var results = (new RegExp(regex)).exec(matches[i]);
					if(results)
					{
						if(results[1] !== '')
						{
							items[results[1]] = decodeURIComponent(results[2]);
						}
						else
						{
							items[VHV.sizeof(items)] = decodeURIComponent(results[2]);
						}
					}
				}
				return items;
			}
		}
		return defaultValue;
	},
	buildURL:function(options, urlMode){
		var url = VHV.staticURL+'?', hasPortal = false;
		for(var i in options)
		{
			if(i == 'site')
			{
				hasPortal = true;
			}
			url += '&'+i+'='+encodeURIComponent(options[i]);
		}
		if(!hasPortal)
		{
			url += '&site='+VHV.App.site;
		}
		return url;
	},
	setAllLinks: function(fileName, value){
		VHV.allLinks[fileName] = value;
		if(VHV.publishModule && fileName.indexOf('3rdparty')==-1 && fileName.indexOf('languages')==-1)
		{
			var rootURL = rootURL.replace(/\//g, '__');
			VHV.allLinks[fileName.replace(/\//g, '__').replace(rootURL, rootURL)] = value;
		}
	},
	read:function(fileName, options, func)
	{
		
		if(!fileName)return;
		
		if(typeof(options) == 'function')
		{
			func = options;
			options = {};
		}
		if(VHV.allLinks[fileName] == 2)
		{
			if(func) func.call(this, VHV.cache[fileName]?VHV.cache[fileName]:'');
			else return VHV.cache[fileName]?VHV.cache[fileName]:'';
			return;
		}
		else
		if(parseInt(VHV.allLinks[fileName]) == 1 && (!options || typeof(options.async)=='undefined' || options.async))
		{
			if(1 || !options || options.async)
			{
				VHV.ExecQueue.add(func, function(){return VHV.allLinks[fileName] == 2}, null, {fileName:fileName});
			}
			else
			{
				func.call(this, VHV.cache[fileName]?VHV.cache[fileName]:'');
			}
			return;
		}
		VHV.setAllLinks(fileName, 1);
		if(!options)
		{
			options = {};
		}
		if(!options.dataType)
		{
			options.dataType = 'html';
		}
		if(typeof(options.async) == 'undefined')
		{
			options.async = VHV.async;
		}
		//fileName = staticURL+fileName.replace(rootURL, '');
		// && (fileName.indexOf(rootURL) == -1)
		//if((fileName.indexOf('http://') != -1) && (fileName.indexOf('.css') == -1))
		if(fileName.indexOf('.js') != -1)
		{
			$.ajax({
				url: staticURL + fileName.replace(rootURL, ''),
				dataType: "script",
				cache: true,
				success: function(){
					VHV.setAllLinks(fileName, 2);
					VHV.allOrderedLinks.push(fileName);
				}
			});
			/*var node = document.createElement('SCRIPT');
			node.src = fileName;
			if($.browser.msie)
			{
				node.onreadystatechange= function () {
					if ((this.readyState == 'complete' || this.readyState == 'loaded') && (VHV.allLinks[realFileName] != 2)){
						
						setTimeout(function(){
							VHV.setAllLinks(fileName, 2);
							VHV.allOrderedLinks.push(fileName);
						}, 100);
					}
				}
			}
			else
			{
				
				node.onload = function(){
					setTimeout(function(){
						VHV.setAllLinks(fileName, 2);
						VHV.allOrderedLinks.push(fileName);
					}, 10);
				};
				
			}
			document.body.appendChild(node);
			return;*/
			/*$('body').append('<'+'script src="'+fileName+'"><'+'/script>');
			VHV.setAllLinks(fileName, 2);
			VHV.allOrderedLinks.push(fileName);*/
		}
		else
		{
			if(fileName.indexOf('.css') != -1)
			{
				var fn = fileName;
				if(fn.indexOf(staticURL) != 0)
				{
					if(fn.charAt(0) == '/')
					{
						
						fn = VHV.staticURL+fn;
					}
					else
					if(fn.indexOf('http://') == -1)
					{
						fn = VHV.staticURL+fn;
					}
				}
				if(fileName.substr(1).indexOf('/')!=-1)
				{
					var fileref=document.createElement("link");
					fileref.setAttribute("rel", "stylesheet");
					fileref.setAttribute("type", "text/css");
					fileref.setAttribute("href", fn);
					document.getElementsByTagName("head")[0].appendChild(fileref);
				}
				VHV.setAllLinks(fileName, 2);
				VHV.allOrderedLinks.push(fileName);
				return;
			}
			
			var realFileName = (VHV.publishModules && fileName.indexOf('.js') != -1 && fileName.indexOf('3rdparty') == -1)?'/publish/modules/'+fileName.replace(/\//g, '_').substr(1):(staticURL+fileName.replace(rootURL, ''));
			
			
			if(fileName.indexOf('.js') != -1 && navigator.userAgent.toLowerCase().indexOf('chrome')==-1 )
			{
				var node = document.createElement('SCRIPT');
				node.src = realFileName;
				if($.browser.msie)
				{
					node.onreadystatechange= function () {
						if ((this.readyState == 'complete' || this.readyState == 'loaded') && (VHV.allLinks[realFileName] != 2)){
							
							setTimeout(function(){
								VHV.setAllLinks(fileName, 2);
								VHV.allOrderedLinks.push(fileName);
							}, 10);
							//if(func) func.call(this);
						}
					}
				}
				else
				{
					
					node.onload = function(){
						
						//VHV.allOrderedLinks.push(fileName);
						setTimeout(function(){
							VHV.setAllLinks(fileName, 2);
							VHV.allOrderedLinks.push(fileName);
						}, 10);
						//if(func) func.call(this);
					};
					
				}
				document.body.appendChild(node);
				
				return;
			}
			var returnValue = '';
			var success = function(data)
				{
					if(fileName.indexOf('.js') == -1 && fileName.indexOf('.css') == -1)
					{
						if (data)					
							VHV.cache[fileName] = data;
					}
					if(options.dataType == 'html')
					{
						if(fileName.indexOf('.css') != -1)
						{
							var parts = fileName.split('/');
							parts.splice(parts.length - 1, 1);
							parts = parts.join('/')+'/';
							data = data.replace(/url\s*\(\s*(["']?)/gi, 'url($1'+parts);
							$('body').append('<style>'+data+'</style>');
						}
						else
						if(fileName.indexOf('.js') != -1)
						{
							eval(data);
						}
					}
					else
					{
						returnValue = data;
					}
					VHV.setAllLinks(fileName, 2);

					VHV.allOrderedLinks.push(fileName);
					if(func)
					{
						func.call(this, data);
					}
				};
			$.ajax($.extend({
				url: realFileName+(/\?/.test(fileName)?'&':'?')+'v='+VHV.version,
				cache:true,
				success:success
			}, options));
			return returnValue;
		}
	},
	getComponentURL:function(url)
	{
		
		var values = {name:url, path : '', type : ''};
		if(url.indexOf('http://') != -1)
		{
			values.path = rootURL + 'get.php?url='+ encodeURI(url);
			values.type = 'cross-domain';
		}
		else if(url.indexOf('3rdparty') != -1 || url.indexOf('languages') != -1 || url.indexOf('.js') != -1 || url.indexOf('.css') != -1)
		{
			values.path = ((url.indexOf(staticURL)!=0)?rootURL:'')+url;
			values.type = '3rdparty';
		}
		else if(url.indexOf('.') != -1)
		{
			var parts = url.split('.'), module = parts.splice(parts.length-1, 1);
			values.package = parts.join('.');
			if(module && module != '')
			{
				if(VHV.publishCode)
				{
					values.path = rootURL+'publish/modules/'+parts.join('__')+'__'+module+'.js';
				}
				else
				{
					values.path = rootURL+parts.join('/')+'/'+module+'.js';
				}
				
				values.type = 'module';
			}
		}
		return values;
	},
	load:function()
	{
		var args = [];
		if(arguments.length>0)
		{
			if(typeof(arguments[0]) == 'function')
			{
				arguments[0].call(this);
			}
			else
			{
				var length = arguments.length;
				if(typeof(arguments[arguments.length - 1]) == 'function')
				{
					length--;
				}
				if(typeof(arguments[0]) == 'object' && arguments[0].length && typeof(arguments[0][0]) == 'object' && arguments[0][0].length)
				{
					var newArgs = args[0].splice(0,1)[0];
					if(args[0].length > 0)
					{
						newArgs.push(function(){
							VHV.load(args[0], args[1]);
						});
					}
					else
					{
						newArgs.push(args[1]);
					}
					VHV.load.apply(this, newArgs);
					return;
				}
				for(var i = 0; i < length; i++)
				{
					if(typeof(arguments[i]) == 'string' && arguments[i])
					{
						args[i] = VHV.getComponentURL(arguments[i]);

						if(!VHV.allLinks[args[i].path])
						{
							var parts = arguments[i].split('.'),currentArg = args[i];
							if(args[i].type == 'module')
							{
								var files = [];
								for(var j = 0; j < parts.length - 1; j++)
								{
									
									var file = 'VHV.'+parts.slice(0, j+1).join('.');
									if(file && file != 'VHV.')
									{
										eval('var model = '+file+';');
										if(typeof(model) == 'undefined')
										{
											eval(file+' = {};');
										}
									}
								}
							}
							if(args[i].path)
							VHV.read(args[i].path);
						}
					}
				}
				if(typeof(arguments[length]) == 'function')
				{
					var oldArgs = arguments;
					
					VHV.ExecQueue.add(function(){
						oldArgs[length].call(this);
					},function(){
						for(var i = 0; i < length; i ++)
						{
							if(args[i])
							{
								if(args[i].type == 'module' && (!VHV.allLinks[args[i].path] || VHV.allLinks[args[i].path] < 2))
								{
									return false;
								}
								else if(args[i].type == 'module')
								{
									var ok = true;
									try{

										eval('ok = (typeof(VHV.'+args[i].name+') != "undefined");');
									}
									catch(e)
									{
										ok = false;
									};
									if(!ok)
									{
										return false;
									}
								}
								else
								if(VHV.allLinks[args[i].path] < 2)
								{
									return false;
								}
							}
						}
						return true;
					}, arguments, {caller:'load', args:args});
				}
			}
		}
	},
	
	using:function(moduleInfo, options, success)
	{
		var moduleName = moduleInfo.module, currentModule = VHV.App.currentModule, moduleId = moduleInfo.id?moduleInfo.id:++VHV.App.maxModuleId;
		if(VHV.App.maxModuleId < moduleId) VHV.App.maxModuleId = moduleId;
		//alert(moduleName)
		VHV.load(moduleName, function(){
			
			VHV.runModule(moduleName, moduleId, $.extend(moduleInfo, options), success, currentModule);
		});
	},
	runModule: function(moduleName, moduleId, options, success, currentModule)
	{
		if(!VHV.App.modules[moduleId])
		{
			var lastModule = VHV.App.currentModule, module;
			VHV.App.currentModule = currentModule;
			eval('module = new VHV.'+moduleName+'('+moduleId+');');

			VHV.App.currentModule = lastModule;
			module.module = moduleName;
			$.extend(module, options);
			module.id = moduleId;
			if(module.modules)
			{
				var modules = {};
				module.applyFunction(function(){
					for(var i in this.modules)
					{
						if(this.modules[i] && this.modules[i].module)
						{
							VHV.using(this.modules[i].module, $.extend({position:i},this.modules[i]), function(){
								modules[this.position] = 1;
							});
						}
					}
				});
				VHV.ExecQueue.add(function(){
					if(module.init)
					{
						module.applyFunction(module.init);
							
					}
					if(success)
					{
						success.call(module);
					}
					//module.initEvents();
				},function(){
					for(var i in module.modules)
					{
						if(i != '#comment' && !modules[i] && module.modules[i].module)
						{
							return false;
						}
					}
					return true;
				}, null, {caller:'runModule '+moduleName});
				return;
			}
			if(module.init)
			{
				module.applyFunction(module.init);
			}
			if(success)
			{
				success.call(module);
			}
			
		}
		else
		{
			module = VHV.App.modules[moduleId];
			$.extend(module, options);
			module.ready(function(){
				module.initEvents();
			});
		}
		
	},
	extend:function(oldClass, properties)
	{
		var newClass = function()
		{
			if(typeof(oldClass) != 'undefined')
			{
				oldClass.apply(this,arguments);
			}
		}
		if(typeof(oldClass) != 'undefined')
		{
			$.extend(newClass.prototype, oldClass.prototype, properties);
		}
		newClass.parentClass = oldClass;
		return newClass;
	},
	sizeof:function(obj)
	{
		if(typeof(obj) == 'object')
		{
			var size = 0;
			for(var i in obj)
			{
				if(typeof(obj[i])!='function')
				{
					size ++;
				}
			}
			return parseInt(size);
		}
		else
		if(typeof(obj)!='undefined' && typeof(obj.length) != 'undefined')
		{
			return obj.length;
		}
		return 0;
	},
	ExecQueue: {
		queue:[],
		isRunning:false,
		interval:false,
		run:function()
		{
			if(!this.interval)
			{
				this.interval = setInterval(this.intervalFunction, 10);
			}
		},
		intervalFunction: function(){
			var that = VHV.ExecQueue;
			if(!that.isRunning)
			{
				that.isRunning = true;
				for(var i = 0; i < that.queue.length; i++)
				{
					if((!that.queue[i].isCalled) && that.queue[i].condition.call(that.queue[i].context))
					{
						that.queue[i].isCalled = true;
						that.queue[i].callback.call(that.queue[i].context);
					}
				}
				var i = 0; 
				while(i < that.queue.length)
				{
					if(that.queue[i].isCalled)
					{
						that.queue.splice(i, 1);
					}
					else
					{
						i ++;
					}
				}
				if(that.queue.length == 0)
				{
					clearInterval(that.interval);
					that.interval = false;
				}
				that.isRunning = false;
			}
		},
		add:function(callback, condition, context, data)
		{
			if(condition.call(context))
			{
				callback.call(context);
			}
			else
			{
				this.queue.push($.extend({
					callback : callback,
					condition : condition,
					context:context,
					isCalled : false
				}, data));
				if(!this.interval)
				{
					this.run();
				}
			}
		}
	},
	App: $.extend({
		portal: '',
		mainPackage: 'Colombo',
		layout:'',
		skin:'',
		version:'1.0',
		modules:{},
		currentPage:false,
		maxModuleId:0,
		currentModule:null,
		image: function(name)
		{
			return VHV.path+'skins/'+VHV.App.skin+'/images/'+name;
		},
		isChild: function(childId, parentId)
		{
			while(childId != -1)
			{
				if(childId == parentId)
				{
					return true;
				}
				if(VHV.App.modules[childId] && VHV.App.modules[childId].parent)
				{
					childId = VHV.App.modules[childId].parent.id;
				}
				else
				{
					return false;
				}
			}
			return false;
		},
		removeModule: function(id)
		{
			if(this.modules[id])
			{
				for(var i in this.modules)
				{
					if(this.modules[i] && this.modules[i].parent && this.modules[i].parent.id == id)
					{
						this.removeModule(this.modules[i].id);
					}
				}
				if(this.modules[id].destructor)
				{
					this.modules[id].destructor();
				}
				delete this.modules[id];
				//this.modules[id] = null;
			}
		}
	}, ReadyObject),
	Module: function(id){
		if(!VHV.App.modules[this.id])
		{
			this.id = id?id:++VHV.App.maxModuleId;
			VHV.App.modules[this.id] = this;
			this.parent = VHV.App.currentModule;
		}
		else
		{
			return VHV.App.modules[this.id];
		}
	}
}, ReadyObject, {
	init:function()
	{
		var pathname = (typeof(applicationPath) != 'undefined')?applicationPath:(location.pathname.substr(rootURL.length));
		
		var path = pathname.split('/');
		VHV.path = (rootURL+path.slice(0, path.length-1).join('/')+(path.length>1?'/':'')).replace(/\/\//g, '/');
		
		VHV.packagePath = rootURL+path.slice(0, path.length-1).join('/')+'/';
		VHV.packageName = path.slice(0, path.length-1).join('.');
		if($.trim(VHV.packageName))
		{
			VHV.App.mainPackage = path.slice(0, path.length-1).join('/');
		}
		//VHV.appName = path[path.length - 2];
		VHV.App.layout = VHV.App.skin = 'Default';
		
		VHV.fileName = path[path.length - 1];
		VHV.allLinks[rootURL+'3rdparty/jQuery/jquery-1.6.2.min.js'] = 2;
		VHV.allLinks[rootURL+'VHV.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'3rdparty/jQuery/jquery-1.6.2.min.js');
		VHV.allOrderedLinks.push(rootURL+'VHV.js');
		VHV.allLinks[rootURL+'3rdparty/jQuery/jquery.cookie.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'3rdparty/jQuery/jquery.cookie.js');
		VHV.allLinks[rootURL+'3rdparty/jQuery/jquery.json/jquery.json.min.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'3rdparty/jQuery/jquery.json/jquery.json.min.js');
		VHV.allLinks[rootURL+'3rdparty/jQuery/pureJSTemplate.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'3rdparty/jQuery/pureJSTemplate.js');
		VHV.allLinks[rootURL+'3rdparty/jQuery/jquery.pagination/jquery.pagination.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'3rdparty/jQuery/jquery.pagination/jquery.pagination.js');
		VHV.allLinks[rootURL+'CMS/Listing.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'CMS/Listing.js');
		VHV.allLinks[rootURL+'CMS/HTML.js'] = 2;
		VHV.allOrderedLinks.push(rootURL+'CMS/HTML.js');
		setTimeout(function(){
		var loader = jQuery('<div id="loader"><img src="'+staticURL+'Colombo/Default/skins/Default/images/loading.gif" alt="loading..." width="50" height="50"/></div>')
			.css({position: "absolute", top: "1em", left: "1em", 'z-index':10000})
			.appendTo("body")
			.hide();
		loader.ajaxStart(function() {
			loader.show();
		}).ajaxStop(function() {
			loader.hide();
		}).ajaxError(function(a, b, e) {
			//throw e;
		});}, 10);
		$.fn.pureJSTemplate.setDelimiters("(*", "*)");
	},
	isInherited: function(childName, parentName)
	{
		
		var childInstance, parentInstance;

		try{
			eval('childInstance = VHV.'+childName+';');
		}
		catch(e)
		{
			return false;
		}
		try{
			eval('parentInstance = VHV.'+parentName+';');
		}
		catch(e)
		{
			return false;
		}
		if(childInstance && parentInstance)
		{
			while(childInstance.parentClass)
			{
				if(childInstance.parentClass === parentInstance)
				{
					return true;
				}
				childInstance = childInstance.parentClass;
			}
			return false;
		}
	}
});
elem = VHV.elem;

$L = Lang = VHV.Lang;

$VHV = function(name, context)
{
	var modules = VHV.App.modules, parentId = -1, path = name.split(' ');
	if(path.length > 1)
	{
		var obj = $VHV(path.splice(0,1), context);
		if(obj) return $VHV(path.join(' '), obj);
		return null;
	}
	if(typeof(context) == 'object')
	{
		parentId = context.id;
	}
	else if(typeof(context) == 'number')
	{
		parentId = context;
	}
	for(var i in modules)
	{
		if(modules[i] && ((modules[i].module == name) || VHV.isInherited(modules[i].module, name)))
		{
			if(parentId == -1 || VHV.App.isChild(modules[i].id, parentId))
			{
				if(typeof(context) == 'function')
				{
					if(context.call(modules[i]))
					{
						return modules[i];
					}
				}
				else
				{
					return modules[i];
				}
			}
			
		}
	}
	return null;
};
$.extend(VHV.Module.prototype,{
	$cache:false,
	data:{},
	layout:'',
	applyFunction:function(func){
		var oldModule = VHV.App.currentModule;
		module = VHV.App.currentModule = this;
		if(typeof(func) == 'function')
		{
			var returnValue = func.call(this);
		}
		else
		{
			var returnValue = this[func]();
		}
		module = VHV.App.currentModule = oldModule;
		return returnValue;
	},
	object: function()
	{
		return 'VHV.App.modules['+this.id+']';
	},
	
	$id: function(id, index) {
		return $('#' + id + ((typeof(index) != 'undefined')?'-'+index:'') + '-' + this.id);
	},
	each: function(f)
	{
		for(var i in VHV.App.modules)
		{
			var module = VHV.App.modules[i];
			if(module && module.parent && module.parent.id == this.id)
			{
				if(f.call(module) === false)
				{
					return;
				}
			}
		}
	},
	params: function()
	{
		var options = {};
		for(var i in this)
		{
			if(i != 'pagingSelector' && i != 'beginTitle' && i != 'class' && i != 'endText' && i != 'endTitle' && i != 'hasController' && i != 'hasPagination' && i != 'index' && i != 'linkTo' && i != 'nextText' && i != 'numDisplayEntries' && i != 'path' && i != 'prevText' && i != 'startText' && i != 'submitFormId' && i != 'totalItems' && i != 'url_mode' && i != 'module' && i != 'id' && (typeof(this[i]) == 'number' || typeof(this[i]) == 'string'))
			{
				options[i] = this[i];
			}
		}
		return options;
	},
	reload: function(options, success)
	{
		if(options)
		{
			$.extend(this, options);
		}
		var module = $('#module'+this.id);
		if(module.length > 0)
		{
			module.load(this.submitURL(
				$.extend({
					cmd: 'redraw'
				}, this.params()))
				, success?success:function(){}
			);
		}
	},
	initEvents: function(){
	},
	$: function()
	{
		if(this.$cache && this.$cache.length > 0)
		{
			return this.$cache;
		}
		else
		{
			this.$cache = $('#module'+this.id);
			return this.$cache;
		}
	},
	html: function(code)
	{
		return this.$().html(code);
	},
	append: function(code)
	{
		return this.$().append(code);
	},
	buildURL:function(options){
		if(!options)
		{
			options = {};
		}
		options.url_mode = VHV.urlMode;
		// khoanb Edit 21.04.09
		var url = rootURL+'?'+((options && options['module'])?'':'module='+this.module)+'&moduleId='+this.id;
		//+'&nd='+(new Date()).getTime();
		if(options)
		{
			for(var i in options)
			{
				url += '&'+i+'='+encodeURIComponent(options[i]);
			}
		}
		return url;
	},
	submitURL:function(options){
		return this.buildURL(options)+'&submitFormId='+this.id+'&moduleId='+this.id+'&page='+this.page+'&site='+VHV.site+'&modulePosition='+this.modulePosition;
	},
	
	formSignature:function()
	{
		return '<input type="hidden" value="'+this.id+'" name="submitFormId">';
	},
	jm:function()
	{
		return 'VHV.App.modules['+this.id+']';
	},
	canView:function()
	{
		return VHV.User.canView(this.moduleName);
	},
	canViewDetail:function()
	{
		return VHV.User.canViewDetail(this.moduleName);
	},
	canAdd:function()
	{
		return VHV.User.canAdd(this.moduleName);
	},
	canEdit:function()
	{
		return VHV.User.canEdit(this.moduleName);
	},
	canAdmin:function()
	{
		return VHV.User.canAdmin(this.moduleName);
	},
	canModerator:function()
	{
		return VHV.User.canModerator(this.moduleName);
	},
	canDeveloper:function()
	{
		return VHV.User.canDeveloper(this.moduleName);
	},
	closeTab:function(obj)
	{
		currentWorkspace.closeTab(obj);
	}
}, ReadyObject, {
	init:function(success)
	{
		if(success && typeof(success) == 'function')
		{
			success.call(this);
		}
		this.isReady = true;
		var that = this;
		$(document).ready(function(){
			that.initEvents();
		});
	},
	ready:function(callback)
	{
		VHV.ExecQueue.add(function(){this.applyFunction(callback);}, function(){return this.isReady && this.$().length;}, this, {caller:'ready'});
	}
});
VHV.Model = function(method)
{
	return VHV.Model.register(method);
}
$.extend(VHV.Model,
{
	engine: {
		serverPath:rootURL+'services.php',
		register:function(serviceModule, methods){
			var model = {};
			for(var i in methods)
			{
				model[i] = this.registerMethod(serviceModule, i);
				model[i].url = this.registerURLMethod(serviceModule, i);
			}
			return model;
		},
		registerMethod: function(serviceModule, method)
		{
			var engine = this;
			return function(options, success){
				return engine.call(serviceModule, method, options, success);
			};;
		},
		registerURLMethod: function(serviceModule, method)
		{
			var engine = this;
			return function(options){
				return engine.url(serviceModule, method, options);
			};;
		},
		call: function(serviceModule, serviceMethod, options, success)
		{
			if(!options)options = {};
			if(!options.site) options.site = VHV.App.site;
			
			var data;
			$.ajax({
				url: this.serverPath, 
				data: $.extend({serviceModule:serviceModule, serviceMethod:serviceMethod},options), 
				async:options.async, 
				type:(!$.toJSON || ($.toJSON(options).length > 2048))?'POST':'GET',
				success: function(response){
					if(success){success.call(this, response);}
					data = response;
				}
			});
			return data;
		},
		url: function(serviceModule, serviceMethod, options)
		{
			if(!options)options = {};
			if(!options.site) options.site = VHV.App.site;
			return this.serverPath+'?'+$.param($.extend({serviceModule:serviceModule, serviceMethod:serviceMethod},options));
		}
	},
	register: function(serviceModule, methods, engine){
		if(!engine)engine = VHV.Model.engine;
		
		var names = serviceModule.split('.'), methodName = '';
		names[names.length-1] = names[names.length-1];
		
		if(!methods){
			methods = {};
			methodName = names.pop();
			methods[methodName] = [];
		}
		
		var obj = VHV.Model;
		for(var i = 0; i < names.length; i++)
		{
			if(!obj[names[i]])
			{
				obj[names[i]] = {};
			}
			obj = obj[names[i]];
		}
		for(var i in methods)
		{
			if(obj[methods[i]])
			{
				delete methods[i];
			}
		}
		var model = VHV.Model.engine.register(names.join('.'), methods);
		$.extend(obj, model);
		if(methodName)
		{
			return obj[methodName];
		}
		return obj;
	}, 
	call: function(serviceModule, serviceMethod, options, success){return VHV.Model.engine.call(serviceModule, serviceMethod, options, success);}
});
module = false;
$.extend(VHV, {
    elems: {},
    serializeForm: function(form, options){
        var defaults = {
            'returnType': '',
            'returnName': 'fields',
			'dateReturn': 'date'
        };
        if (typeof(options) != 'object') {
            options = defaults;
        }
        else {
            options = $.extend(defaults, options);
        }
        var values = $(form).serializeArray(), fields = {};
		var formId = $(form).attr('id');
        for (var i = 0; i < values.length; i++) {
            var name = 'fields.' + values[i].name;
			if (options.dateReturn == 'number') {
				var dp = $('#' + formId + ' input[name='+values[i].name+'].hasDatepicker');
				if (dp.length != 0) {
					try {
						var value = '';
						var date = dp.datepicker('getDate');
						if (date) {
							value = date.getUTCTime() / 1000;
						}
						values[i].value = value;
					} catch (ex) {
						values[i].value = '';
					}
				}
			}
            name = name.replace(/\.([\w\-]+)/g, '[\'$1\']');
            var path = name.split('[');
            for (var j = 1; j < path.length - 1; j++) {
                var subName = path.slice(0, j + 1).join('[');
                eval('var value = ' + subName + ';');
                if (!value) {
                    eval(subName + ' = {};');
                }
            }
            eval(name + '=$.trim(values[i].value);');
        }
        if (options['returnType'] == 'submitArray') {
            var params = {};
            for (var i in fields) {
                params[options.returnName + '[' + i + ']'] = fields[i];
            }
            return params;
        }
        else {
            return fields;
        }
    },
    elem: function(id){
        var elem = VHV.elems[id];
        if (!elem) {
            return (VHV.elems[id] = document.getElementById(id));
        }
        return elem;
    },
	prompt: function(title, message, callback, options)
	{
		VHV.load('3rdparty/jQuery/fbmodal/jquery.fbmodel.css');
		VHV.load('3rdparty/jQuery/fbmodal/jquery.fbmodel.js', function(){
			var div = $('<div style="display:none">'+message+'<br><textarea style="width:100%" onkeypress="VHV.promptMessage = this.value;"></textarea></div>').appendTo($('body'));
			div.fbmodal($.extend({
				title: title,  
				cancel: 'Cancel',
				okay: 'Ok',
				okaybutton: true,
				cancelbutton: true,
				buttons: true,
				opacity: 0.0,
				fadeout: true,
				overlayclose: true,
				modaltop: "30%",
				modalwidth: "400",
				callback: callback,
				success: function(){
					div.remove();
					$('#fbmodal_overlay').remove();
				}
			}, options));
		});
	},
	confirm: function(title, message, callback, options)
	{
		VHV.load('3rdparty/jQuery/fbmodal/jquery.fbmodel.css');
		VHV.load('3rdparty/jQuery/fbmodal/jquery.fbmodel.js', function(){
			var div = $('<div style="display:none">'+message+'</div>').appendTo($('body'));
			div.fbmodal($.extend({
				title: title,  
				cancel: 'Cancel',
				okay: 'Ok',
				okaybutton: true,
				cancelbutton: true,
				buttons: true,
				opacity: 0.0,
				fadeout: true,
				overlayclose: true,
				modaltop: "30%",
				modalwidth: "400",
				callback: callback,
				success: function(){
					div.remove();
					$('#fbmodal_overlay').remove();
				}
			}, options));
		});
	},
    alert: function(message, options){
		VHV.load('3rdparty/jQuery/jGrowl/jquery.jgrowl.css');
		VHV.load('3rdparty/jQuery/jGrowl/jquery.jgrowl_minimized.js', function(){
			$.jGrowl(message, options);
		});
    },
    dialog: function(moduleName, data, options, onClose, onOpen){
		var _default = {
			title:'',
			onClose:'',
			onOpen:'',
			height:800,
			width:960,
			zIndex:2000
		};
		if(typeof(options) == 'function')
		{
			options = {
				success:options
			}
		}
		if(typeof(options) != 'undefined'){
			options = $.extend(_default, options);
		}
		else{
			options = _default;
		}
		if(typeof(onClose) == 'function'){
			options.onClose = onClose;
		}
		if(typeof(onOpen) == 'function'){
			options.onOpen = onOpen;
		}
        var div = $('<div></div>'), moduleId;
        $('body').append(div);
        if (moduleName.indexOf('<') != -1) {
            div.html(moduleName);
            options = data;
        }
        else {
			moduleId = VHV.App.maxModuleId + 10;
			moduleId = div.loadModule(moduleName, data, function(){
				if(moduleId && VHV.App.modules[moduleId])
				{
					VHV.App.modules[moduleId].dialog = div;
				}
				if(options.success)
				{
					options.success.call(VHV.App.modules[moduleId]);
				}
			});
			
        }
        VHV.load('3rdparty/jQuery/jqueryui/themes/smoothness/jquery-ui.css');
        VHV.load('3rdparty/jQuery/jqueryui/jquery-ui.min.js', function(){
           
			div.dialog(options);
			if(typeof(options.onOpen) == 'function')
			{
				setTimeout(function(){options.onOpen.call(this);}, 1);
			}
			div.bind('dialogclose', function(){
				if (typeof(options.onClose) == 'function') {
					options.onClose.call(this);
				}
				if (moduleId) {
					VHV.App.removeModule(moduleId);
				}
			});
        });
		if (typeof(onCLose) == 'object') {
            if (typeof(onClose.onOpen) == 'function') {
                onClose.onOpen.call(this);
            }
        }
		return div;

        
    },
    cookie: function(name, value, expires){
		if($.cookie)
		{
			if (typeof(value) == 'undefined') {
				return $.cookie(name);
			}
			else {
				//expires = expires ? expires : 1 / 24;
				var parts = VHV.domain.split('.');
				$.cookie(name, value, {
					path: '/'
					//domain: '.'+parts[parts.length - 2]+'.'+parts[parts.length - 1],
					//expires: expires
				});
			}
		}
    },
	embed: function(options)
	{
		if(!options.url) return '';
		var url = parseUri(options.url);
		if(!url.host)
		{
			return this._embed.url(options);
		}
		if(options.url.lastIndexOf('.swf')!=-1)
		{
			return this._embed.swf(options);
		}
		switch(url.host)
		{
			case 'www.youtube.com':
			case 'youtube.com':
			case 'youtu.be':
			case 'www.youtube-nocookie.com':
			case 'youtube-nocookie.com':
				return this._embed.youtube(options);
				break;			
			case 'www.vimeo.com':
			case 'vimeo.com':
				return this._embed.vimeo(options);
				break;
			case 'www.clip.vn':
			case 'clip.vn':
				return this._embed.clipvn(options);
				break;
			case 'video.zing.vn':
				return this._embed.zingvn(options);
				break;
			case 'video.tamtay.vn':
				return this._embed.tamtayvn(options);
				break;
			default:
				return this._embed.url(options);
				break;
		}
	},
	_embed: {
		youtube: function(options){
			var $id = this.getIdYoutube(options.url);
			var $w = typeof options.width == 'undefined' ? 400 : options.width;
			var $h = typeof options.height == 'undefined' ? 255 : options.height;
			return '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="mediaplayer1" name="mediaplayer1" width="'+$w+'" height="'+$h+'"><param name="movie" value="http://colombo.vn/3rdparty/jwplayer/player.swf"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="bgcolor" value="#000000"><param name="wmode" value="opaque"><param name="flashvars" value="file=http://www.youtube.com/watch%3Fv%3D'+$id+'"><embed id="mediaplayer1" name="mediaplayer2" src="http://colombo.vn/3rdparty/jwplayer/player.swf" width="'+$w+'" height="'+$h+'" allowfullscreen="true" allowscriptaccess="always" bgcolor="#000000" wmode="opaque" flashvars="file=http://www.youtube.com/watch%3Fv%3D'+$id+'"/></object>';
		},
		url: function(options){
			var $ext = options.url.substr(options.url.lastIndexOf('.'), options.url.length);
			switch($ext)
			{
				case '.jpeg':
				case '.jpg':
				case '.png':
				case '.bmp':
				case '.gif':
					return this.image(options);
					break;
				case '.flv':
				case '.mp4':
				case '.wmv':
					return this.swf(options);
					break;
				default:
					return this.swf(options);
					break;
			}
		},
		swf: function(options){
			var $url = options.url;
			if(options.url.substr(7)!='http://')
			{
				$url = staticUrl+$url;
			}
			var $w = typeof options.width == 'undefined' ? 400 : options.width;
			var $h = typeof options.height == 'undefined' ? 255 : options.height;
			return '<embed id="mediaplayer1" name="mediaplayer2" src="'+$url+'" width="'+$w+'" height="'+$h+'" allowfullscreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" bgcolor="#000000" wmode="transparent" align="middle" quality="high"/>';
		},
		vimeo: function (options){
			var $id = this.getIdVimeo(options.url);
			var $w = typeof options.width == 'undefined' ? 400 : options.width;
			var $h = typeof options.height == 'undefined' ? 255 : options.height;
			return '<object width="'+$w+'" height="'+$h+'"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id='+$id+'&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff000d&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed src="http://vimeo.com/moogaloop.swf?clip_id='+$id+'&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff000d&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="'+$w+'" height="'+$h+'"></embed></object>';
		},
		getIdYoutube: function (url){
			var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
			var match = url.match(regExp);
			if (match&&match[7].length==11){
				return match[7];
			}
			else
			{
				return '';
			}
		},
		getIdVimeo: function (url){
			//var url = "http://www.vimeo.com/7058755";
			var regExp = /http:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/;			
			var match = url.match(regExp);			
			if (match)
				return match[2];
			else
				return '';
		},
		getImageYoutube: function(url, type){//type= 'default | small | large'
			var id = this.getIdYoutube(url);
			return 'http://i1.ytimg.com/vi/'+id+'/'+(typeof(type)!='undefined'?type:'default')+'.jpg';
		}
	},
	url:function(item)
	{
		if(item && item.rewriteURL)
		{
			return item.rewriteURL;
		}
		return item?'/?id='+item['id']:'/';
	},
	image: function(url, size, type)
	{
		if(size&&url.indexOf('http://')==-1)
		{
			if(!type)type='default';
			return VHV.staticURL+'publish/thumbnail/'+VHV.App.mainPackage.replace('/','_')+'/'+size+'x'+type+('/'+url).replace('//','/');
		}
		return url;
	},
	addToCart: function(params, redirect){
		VHV.Model('Ecommerce.Cart.addProduct')(params, function(result){
			if(redirect)
			{
				location = '?page=cart&site='+VHV.App.site;
			}
			else
			{
				eval('result='+result+';');
				if($('.cart-total-items').length)
				{
					$('.cart-total-items').text(result.totalItems);
				}
				if($('.cart-total-amount').length)
				{
					$('.cart-total-amount').text(result.totalAmount);
				}
				if($('#cart-footer').length)
				{
					$('#cart-footer').animate({
						right: '-115px'
					});
				}
				VHV.alert('Đã thêm vào giỏ hàng!');
			}
		});
	},
	cloneMultipleRow: function(name, trCode, obj)
	{
		var code = trCode, lastCode = obj.find(' > tbody > tr:last').html();
		
		if(lastCode.match(/\]\[(\d+)\]\[/) || trCode.match(/\]\[(\d+)\]\[/))
		{
			code = code?code.replace(/\]\[(\d+)\]\[/g, ']['+(parseInt(RegExp.$1)+1)+']['):'';
			obj.append('<tr>'+code+'</tr>');
			obj.find('tr:last td').each(function(){
				var code = $(this).html();

				if(code.indexOf('id="uploader') != -1 && code.match(/name="fields\[\w+\]\[(\d+)\]\[(\w+)\]"/))
				{
					var id = new Date().getTime();
					$(this).html('<input type="file" id="uploader'+id+'"/><input type="hidden" id="input'+id+'" name="fields['+name+']['+RegExp.$1+']['+RegExp.$2+']"/><div id="imageResult'+id+'"></div>');
					VHV.load('3rdparty/jQuery/jquery.uploadify/uploadify.css');
VHV.load('3rdparty/jQuery/jquery.uploadify/jquery.uploadify.v2.1.4.js',
		 '3rdparty/jQuery/jquery.uploadify/swfobject.js', function(){
						$('#uploader'+id).uploadify({
							uploader: VHV.rootURL+'3rdparty/jQuery/jquery.uploadify/uploadify.swf',
							script: VHV.rootURL+'upload.php?site='+VHV.App.portal,
							auto: 1,
							buttonImg: VHV.rootURL+"3rdparty/jQuery/jquery.uploadify/button_file.png",
							buttonText: "Chọn file",
							cancelImg: VHV.rootURL+"3rdparty/jQuery/jquery.uploadify/cancel.png",
							fileExt: "*.jpg;*.png;*.gif;*.jpeg;*.bmp;*.doc;*.docx;*.xls;*.xlsx;*.ppt;*.pptx;*.pdf",
							height: 25,
							width: 80,
							multi: 1,
							onComplete: function(event, queueID, fileObj, response, data) {
								$('#input'+id).val(response);
								if(fileObj.type=='.jpg' || fileObj.type=='.gif' || fileObj.type=='.png' || fileObj.type=='.jpeg')
								{
									$('#imageResult'+id).html('<img src="'+VHV.rootURL+response+'" width="100" />');
								}
							}
						});
					});
				}
				if(code.indexOf('class="colorSelector') != -1)
				{
					var id = new Date().getTime();
					$(this).html('<div class="colorSelector" onclick="$(this.parentNode.previousSibling.firstChild).trigger(\'click\');"><div style="background-color:"></div></div>');
					$(this).prev().find('input').attr('id', 'input'+id);
					VHV.load('3rdparty/jQuery/colorpicker/css/colorpicker.css');
					VHV.load('3rdparty/jQuery/colorpicker/js/colorpicker.js', function(){
						$('#input'+id).ColorPicker({
							livePreview: true, 
							onSubmit: function(hsb, hex, rgb, el) {
								$(el).val('#'+hex);
								$(el.parentNode.nextSibling.firstChild).css('background-color','#'+hex);
								$(el).ColorPickerHide();
								//$('#thanh1').val('#'+hex);
							},
							onBeforeShow: function () {
								if(this.value) $(this).ColorPickerSetColor(this.value.substr(1));
							}
						}).bind('keyup', function(){
							if(this.value){ 
								$(this).ColorPickerSetColor(this.value.substr(1));
								$(this.parentNode.nextSibling.firstChild).css('background-color','#'+this.value.substr(1));
							}
						});
					});
				}
			});
		}
	}
});
String.prototype.ucfirst = function(){
    var st = this.toString();
    if (st.length > 0) {
        return st.charAt(0).toUpperCase() + st.substr(1).toLowerCase();
    }
    else {
        return '';
    }
};
String.prototype.ucwords = function(){
    var st = this.toString().replace(/\_/g, ' ');
    var sts = st.split(' ');
    for (var i = 0; i < sts.length; i++) {
        sts[i] = sts[i].ucfirst();
    }
    return sts.join('');
};

$.fn.loadModule = function(moduleName, settings, onComplete){
    var moduleId = parseInt(VHV.App.maxModuleId)+10;
	VHV.App.maxModuleId = moduleId;
    $(this).each(function(){
		var that = $(this);
		that.load(VHV.buildURL($.extend({module:moduleName, moduleId:moduleId}, settings)), function(){
			if (typeof(this.onOpen) == 'function') 
				this.onOpen();
			if (typeof(onComplete) == 'function') {
				onComplete.call(this, moduleId);
			}
        });
    });
    return moduleId;
};
Date.prototype.format = function(format) {
	var returnStr = '';
	var replace = Date.replaceChars;
	for (var i = 0; i < format.length; i++) {
		var curChar = format.charAt(i);
		if (replace[curChar]) {
			returnStr += replace[curChar].call(this);
		} else {
			returnStr += curChar;
		}
	}
	return returnStr;
};

Date.prototype.getUTCTime = function() {
   return this.getTime() - 60000 * Date.getTimezoneOffset();
}

Date.getTimezoneOffset = function() {
	if (!this.defaultTimezoneOffset) {
		this.defaultTimezoneOffset = (new Date()).getTimezoneOffset();
	}
	return this.defaultTimezoneOffset;
}

Date.replaceChars = {
	shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	longMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
	longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
	
	// Day
	d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
	D: function() { return Date.replaceChars.shortDays[this.getDay()]; },
	j: function() { return this.getDate(); },
	l: function() { return Date.replaceChars.longDays[this.getDay()]; },
	N: function() { return this.getDay() + 1; },
	S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
	w: function() { return Date.replaceChars.shortDays[this.getDay()]; },
	
	z: function() { return "Not Yet Supported"; },
	// Week
	W: function() { return "Not Yet Supported"; },
	// Month
	F: function() { return Date.replaceChars.longMonths[this.getMonth()]; },
	m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
	M: function() { return Date.replaceChars.shortMonths[this.getMonth()]; },
	n: function() { return this.getMonth() + 1; },
	t: function() { return "Not Yet Supported"; },
	// Year
	L: function() { return (((this.getFullYear()%4==0)&&(this.getFullYear()%100 != 0)) || (this.getFullYear()%400==0)) ? '1' : '0'; },
	o: function() { return "Not Supported"; },
	Y: function() { return this.getFullYear(); },
	y: function() { return ('' + this.getFullYear()).substr(2); },
	// Time
	a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
	A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
	B: function() { return "Not Yet Supported"; },
	g: function() { return this.getHours() % 12 || 12; },
	G: function() { return this.getHours(); },
	h: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
	H: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
	i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
	s: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
	// Timezone
	e: function() { return "Not Yet Supported"; },
	I: function() { return "Not Supported"; },
	O: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00'; },
	P: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':' + (Math.abs(this.getTimezoneOffset() % 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() % 60)); },
	T: function() { var m = this.getMonth(); this.setMonth(0); var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); this.setMonth(m); return result;},
	Z: function() { return -this.getTimezoneOffset() * 60; },
	// Full Date/Time
	c: function() { return this.format("Y-m-d") + "T" + this.format("H:i:sP"); },
	r: function() { return this.toString(); },
	U: function() { return this.getTime() / 1000; }
};
window.VHV.init();
mainPackage = VHV.App.mainPackage;

function parseUri (str) {
	var	o   = parseUri.options,
		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i   = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};;
/*PieNG*/
if (/MSIE [56].*Windows/.test(navigator.userAgent)) (function() {
	//Internet Explorer for Windows
	var blank = new Image;
	blank.src = "/colombo/Colombo/Default/skins/Default/images/blank.gif";
	var imgs = document.getElementsByTagName("img");
	for (var i = 0; i < imgs.length; i++){
		var img = document.images[i];
		var src = img.src;
		if (!/\.png$/.test(src))
			continue;
		var s = img.runtimeStyle;
		s.width = img.offsetWidth + "px";
		s.height = img.offsetHeight + "px";
		s.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='scale')";
		img.src = blank.src;
	}
})();
VHV.getTime = function(){
	return Math.round(new Date().getTime()/1000)-VHV.localTime+VHV.serverTime;
};
VHV.ready = true;
initVHV = true;
VHV.CMS = {};
VHV.CMS.Listing = VHV.extend(VHV.Module,
{
	filters:{},
	orderBy:'',
	type:'',
	pagingSelector:false,
	pageNo:1,
	itemsPerPage:20, 
	numDisplayEntries: 5,
	totalItems:0,
	nextText:'&raquo;',
	prevText:'&laquo;',
	startText:'&laquo;&laquo;',
	endText:'&raquo;&raquo;',
	linkTo:'javascript:void(0);',
	fields:[],
	comboboxes:{},
	showControl: true,
	init:function(success)
	{
		var that = this;
		if(!this.pagingSelector)
		{
			this.pagingSelector = '.pagination'+this.id+',#pagination'+this.id;
		}
		VHV.load('3rdparty/jQuery/jquery.pagination/jquery.pagination.js', function(){
			VHV.Module.prototype.init.call(that,success);
		});
	},
	initEvents: function()
	{
		if(this.pagingSelector)
		{
			var pager = $(this.pagingSelector);
			if(pager.length > 0)
			{
				this.itemsPerPage = parseInt(this.itemsPerPage);
				this.totalItems = parseInt(this.totalItems);
				if(this.itemsPerPage < this.totalItems)
				{
					var that = this, options = {
						callback : function(currentPage,obj){
							that.pageNo = currentPage+1;
							that.reload();
						},
						current_page: this.pageNo-1,
						items_per_page: this.itemsPerPage, 
						num_display_entries: this.numDisplayEntries,
						next_text: this.nextText,
						prev_text: this.prevText,
						start_text: this.startText,
						end_text: this.endText,
						link_to: 'javascript:void(0);',
						prev_show_always:this.showControl?true:false,
						next_show_always:this.showControl?true:false
					};
					pager.show();
					var that = this;
					VHV.load('3rdparty/jQuery/jquery.pagination/jquery.pagination.js', function(){
						pager.pagination(that.totalItems,options);
					});
				}
				else
				{
					pager.hide();
				}
			}
		}
	},
	sort:function(column)
	{
		var that=this;
		if (typeof(this.fields[column])=='undefined')
		{
			this.fields[column]=0;
		}
		else
		{
			this.fields[column]=1-this.fields[column];
		}
		if (this.fields[column]==1)			
			this.orderBy=column + ' asc';							
		else
			this.orderBy=column + ' desc';									
		this.reload({},function(){
			that.afterReload();
			if (that.fields[column]==1)
				$('#sort-icon-'+column+that.id).attr('src','Colombo/Default/skins/Default/images/asc.gif');
			else
				$('#sort-icon-'+column+that.id).attr('src','Colombo/Default/skins/Default/images/desc.gif');					
		});
	},
	afterReload:function()
	{
		
	},	
	initFilters:function()
	{
		var that = this;
		for(var i in this.comboboxes)
		{
			$('#filter_'+i+this.id+',.filter_'+i).each(function(){
				for(var j in that.comboboxes[i])
				{
					this.add(new Option(that.comboboxes[i][j].name, that.comboboxes[i][j].id, false, false), null);
				}
			}).val(VHV.request(i)).change(function(){
				that.addCondition(i,$(this).val());
				that.reload();
			});
		}
	},
	addFilter:function(name, value, multi, filterName)
	{
		this.pageNo = 1;
		if(typeof(filterName) == 'undefined')
		{
			filterName = 'filters';
		}
		if(multi)
		{
			if(this.filters[filterName+'['+name+']'])
			{
				if(this.filters[filterName+'['+name+']'].indexOf(value)!=-1)
				{
					return;
				}
				this.filters[filterName+'['+name+']'] += '||'+value;
				return;
			}
		}
		if(typeof(this.filters) != 'undefined'){
			this.filters[filterName+'['+name+']'] = value;
		}
	},
	removeFilter:function(name, multi, value, filterName)
	{
		if(typeof(filterName) == 'undefined')
		{
			filterName = 'filters';
		}
		if(multi)
		{
			this.filters[filterName+'['+name+']'] = this.filters[filterName+'['+name+']'].replace('||'+value,'').replace(value+'||','');
			if(this.filters[filterName+'['+name+']'] != value)
			{
				return;
			}
		}
		delete this.filters[filterName+'['+name+']'];
	},
	addCondition:function(name, value, multi)
	{
		this.addFilter(name, value, multi,'condition');
	},
	removeCondition:function(name, multi, value)
	{
		this.removeFilter(name, value, multi,'condition');
	},
	orderFillter:function(value)
	{
		$('.content-order'+this.id).load(this.submitURL({cmd: 'redrawList', status:value}))
	},
	success:function()
	{
		this.initEvents();
	},
	orderBy:function(field, defaultDir)
	{
		if(typeof(defaultDir)=='undefined')
		{
			defaultDir = 'asc';
		}
		if(this.orderBy == (field+' '+defaultDir))
		{
			defaultDir = (defaultDir == 'asc')?'desc':'asc';
		}
		this.orderBy = field+' '+((defaultDir == 'asc')?'asc':'desc');
		this.reload();
	}
});;VHV.CMS.HTML = VHV.extend(VHV.Module,{
	
});;
