function preg_print_pre(obj, reg)
{
	if (!reg) reg = /.*/;
	var p = ''
	for (var prop in obj) {
		if (prop.match(reg) ) {
			p += prop + ': '+obj[prop] + '\n'
		}
	}
	alert(p)
}


// Main AJAX classs
function Request() {}

Request.timeout = 15000; //5 seconds
Request.method = 'GET';
Request.headers = new Array();
Request.params = null;

Request.makeRequest = function(p_url, p_busyReq, p_progId, p_successCallBack, p_errorCallBack, p_pass, p_object) {
	//p_url: the web service url
	//p_busyReq: is a request for this object currently in progress?
	//p_progId: element id where progress HTML should be shown
	//p_successCallBack: callback function for successful response
	//p_errorCallBack: callback function for erroneous response
	//p_pass: string of params to pass to callback functions
	//p_object: object of params to pass to callback functions

	if (p_busyReq) return;
	var req = Request.getRequest();
	if (req != null) {
		p_busyReq = true;
		Request.showProgress(p_progId);
		req.onreadystatechange = function() {
			if (req.readyState == 4) {
				p_busyReq = false;
				window.clearTimeout(toId);
				try {
					if (req.status == 200) {
	//					preg_print_pre(req)
						p_successCallBack(req, p_pass, p_object);
					} else {
						p_errorCallBack(req, p_pass, p_object);
					}
					Request.hideProgress(p_progId);
				}
				catch (e) {
//					alert('AJAX error')
				}
			}
		}
		var $ajax_mark = (p_url.indexOf('?') ? '&' : '?') + 'ajax=yes';
		req.open(Request.method, p_url + $ajax_mark, true);

		if (Request.method == 'POST') {
			Request.headers['Content-type'] = 'application/x-www-form-urlencoded';
			Request.headers['referer'] = p_url;
		}
		else {
			Request.headers['If-Modified-Since'] = 'Sat, 1 Jan 2000 00:00:00 GMT';
		}

		Request.sendHeaders(req);
		if (Request.method == 'POST') {
			req.send(Request.params);
			Request.method = 'GET'; // restore method back to GET
		}
		else {
			req.send(null);
		}

		var toId = window.setTimeout( function() {if (p_busyReq) req.abort();}, Request.timeout );
	}
}

Request.sendHeaders = function($request) {
	for (var $header_name in Request.headers) {
		if (typeof Request.headers[$header_name] == 'function') {
			continue;
		}
		$request.setRequestHeader($header_name, Request.headers[$header_name]);
	}
	Request.headers = new Array(); // reset header afterwards
}

Request.getRequest = function() {
	var xmlHttp;
	try { xmlHttp = new ActiveXObject('MSXML2.XMLHTTP'); return xmlHttp; } catch (e) {}
	try { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); return xmlHttp; } catch (e) {}
	try { xmlHttp = new XMLHttpRequest(); return xmlHttp; } catch(e) {}
	return null;
}

Request.showProgress = function(p_id) {
	if (p_id != '') {
		Request.setOpacity(20, p_id);

		if (!document.getElementById(p_id + '_progress')) {
			document.body.appendChild(Request.getProgressObject(p_id));
		}
		else {
			var $progress_div = document.getElementById(p_id + '_progress');
			$progress_div.style.top = getRealTop(p_id) + 'px';
			$progress_div.style.height = document.getElementById(p_id).clientHeight;
			$progress_div.style.display = 'block';
		}
//		document.getElementById(p_id).innerHTML = Request.getProgressHtml();
	}
}

Request.hideProgress = function(p_id) {
	if (p_id != '') {
		document.getElementById(p_id + '_progress').style.display = 'none';
		Request.setOpacity(100, p_id);
	}
}

Request.setOpacity = function (opacity, id) {
    var object = document.getElementById(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
}

Request.getProgressHtml = function() {
	return "<p class='progress'>" + Request.progressText + "<br /><img src='img/ajax_progress.gif' align='absmiddle' width='100' height='7' alt='" + Request.progressText + "'/></p>";
}

Request.getProgressObject = function($id) {
	var $div = document.createElement('DIV');
	var $parent_div = document.getElementById($id);

	$div.id = $id + '_progress';

	$div.style.width = $parent_div.clientWidth + 'px';
	$div.style.height = '150px'; // default height if div is empty (first ajax request for div)
	$div.style.left = getRealLeft($parent_div) + 'px';
	$div.style.top = getRealTop($parent_div) + 'px';
	$div.style.position = 'absolute';

	/*$div.style.border = '1px solid green';
	$div.style.backgroundColor = '#FF0000';*/

	$div.innerHTML = '<table style="width: 100%; height: 100%;"><tr><td style="text-align: center;">'+Request.progressText+'<br /><img src="img/ajax_progress.gif" align="absmiddle" width="100" height="7" alt="'+escape(Request.progressText)+'" /></td></tr></table>';
	return $div;
}

Request.getErrorHtml = function(p_req) {
	//TODO: implement accepted way to handle request error
	return '[status: ' + p_req.status + '; status_text: ' + p_req.statusText + '; responce_text: ' + p_req.responseText + ']';
}

Request.serializeForm = function(theform) {
	if (typeof(theform) == 'string') {
		theform = document.getElementById(theform);
	}

	var els = theform.elements;
	var len = els.length;
	var queryString = '';

	Request.addField = function(name, value) {
		if (queryString.length > 0) queryString += '&';
		queryString += encodeURIComponent(name) + '=' + encodeURIComponent(value);
	};

	for (var i = 0; i<len; i++) {
		var el = els[i];
    	if (el.disabled) continue;

		switch(el.type) {
			case 'text':
			case 'password':
			case 'hidden':
			case 'textarea':
          		Request.addField(el.name, el.value);
				break;

			case 'select-one':
				if (el.selectedIndex >= 0) {
            		Request.addField(el.name, el.options[el.selectedIndex].value);
          		}
          		break;

			case 'select-multiple':
				for (var j = 0; j < el.options.length; j++) {
            		if (!el.options[j].selected) continue;
              		Request.addField(el.name, el.options[j].value);
          		}
          		break;

			case 'checkbox':
			case 'radio':
          		if (!el.checked) continue;
            	Request.addField(el.name,el.value);
          		break;
      	}
	}
	return queryString;
};

// AJAX PopupManager class
function AjaxContactsManager($url, $respoce_func) {
	this.URL = $url;
	this.LoadingText = 'Loading ...';
	this.aSelect = null;
}

AjaxContactsManager.prototype.GetContacts = function ($folder_id, $select_id, $exceptions) {
	var $url = this.URL.replace('#FOLDER_ID#', $folder_id).replace('#EXCEPTIONS#', $exceptions);

	this.aSelect = document.getElementById($select_id);
	this.clearDropdown();
	this.addDropdownOption(0, this.LoadingText);
	Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}

AjaxContactsManager.prototype.successCallback = function($request, $params, $object) {
	var $responce = $request.responseText;
	var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
	if ($match_redirect != null) {
		// redirect to external template requested
		window.location.href = $match_redirect[1];
		return false;
	}

	var $contacts = new Array ();
	if ($responce.length) {
		$contacts = $responce.split('|');
	}

//	$object.aSelect = document.getElementById($params);
	$object.clearDropdown();

	var $i = 0;
	while ($i < $contacts.length) {
		$object.addDropdownOption($i, $contacts[$i]);
		$i++;
	}
}

AjaxContactsManager.prototype.clearDropdown = function() {
	while (this.aSelect.options.length) {
		this.aSelect.remove(0);
	}
}

AjaxContactsManager.prototype.addDropdownOption = function($value, $name) {
	var $new_option = document.createElement('OPTION');
	this.aSelect.options.add($new_option);
	$new_option.innerText = $new_option.innerHTML = $name;
	$new_option.value = $value;
}

AjaxContactsManager.prototype.errorCallback = function($request, $params, $object) {
	alert('AJAX Error; class: AjaxContactsManager; ' + Request.getErrorHtml($request));
}

// AJAX MessageIndicator class
function AjaxMessageIndicator($new_messages, $url, $flash_title) {
	this.NewMessages = $new_messages;
	this.URL = $url;
	this.BusyRequest = false;
	this.DefaultTitle = window.document.title;
	this.FlashTitle = $flash_title;
	this.IntervalId = setInterval('aMessageIndicator.' + (this.NewMessages ? 'flashMessage()' : 'Query()'), this.NewMessages ? 1000 : 60 * 1000);
}

AjaxMessageIndicator.prototype.flashMessage = function() {
	window.document.title = window.document.title == this.DefaultTitle ? this.FlashTitle : this.DefaultTitle;
}

AjaxMessageIndicator.prototype.Query = function() {
	Request.makeRequest(this.URL, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}

AjaxMessageIndicator.prototype.successCallback = function($request, $params, $object) {
	var $responce = $request.responseText;
	var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
	if ($match_redirect != null) {
		// redirect to external template requested
		window.location.href = $match_redirect[1];
		return false;
	}

	if (parseInt($responce) > 0) {
		window.location.href = window.location.href; // reload using GET method
	}
}

AjaxMessageIndicator.prototype.errorCallback = function($request, $params, $object) {
	//alert('AJAX Error; class: AjaxMessageIndicator; ' + Request.getErrorHtml($request));
}


// Rating Collector
function RatingCollector($url, $avg_rating, $votes_counter_id, $voting_result_id, $already_voted, $IndicatorId, $TemplatesBase) {
	this.BusyRequest = false;
	this.URL = $url;
	this.AvgRating = parseFloat($avg_rating);
	this.IndicatorId = $IndicatorId;
	this.Debug = 0;
	this.AlreadyVoted = $already_voted;
	this.VotesCounterID = $votes_counter_id;
	this.VotingResultID = $voting_result_id;
	this.TemplatesBase = $TemplatesBase;
}

RatingCollector.prototype.successCallback = function($request, $params, $object) {
	var $responce = $request.responseText;
	var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
	if ($match_redirect != null) {
		// redirect to external template requested
		window.location.href = $match_redirect[1];
		return false;
	}

	var $rating = $responce.split('|');
	$object.AvgRating = parseFloat($rating[2]);
//	$object.AvgRating = parseFloat($rating[0]);
	$object.SetRatingStatus(0, 0);
	ospan = document.getElementById("votes_" + $object.IndicatorId);
	if (ospan) {
		ospan.innerHTML = $rating[1];	
	}
	$object.AlreadyVoted = true;

//	setTimeout( function () {$object.ClearVotingStatus(); }, 1500);
// 0 - avg question rating
// 1 - quiestion answers count
// 2 - current patients rating
// 3 - question asked patients rating
// 4 - doctor1 patients rating
// 5 - doctor2 patients rating
// 6 - doctor1 answers count
// 7 - doctor2 answers count
// 8 - doctor1 ID
// 9 - doctor2 ID
}

RatingCollector.prototype.ClearVotingStatus = function() {
	document.getElementById(this.VotingResultID).innerHTML = '';
}

RatingCollector.prototype.errorCallback = function($request, $params, $object) {
//	alert('AJAX Error; class: ClickCounter; ' + Request.getErrorHtml($request));
}

RatingCollector.prototype.SaveRating = function ($rating) {
	if (this.AlreadyVoted) {
		// don't process if already voted
		return ;
	}

	var $url = this.URL.replace('#RATING#', $rating);
	Request.headers = new Array();
	Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}

RatingCollector.prototype.SetStarStatus = function ($star_number, $active) {
	if (this.AlreadyVoted) {
		// don't process if already voted
		return ;
	}

	var $new_image = this.TemplatesBase + 'img/star_g_' + ($active ? (($active == 0.5) ? '0' : '1') : '2')  + '.png';
	var $star = document.getElementById("star"+this.IndicatorId+"_" + $star_number);

	if (GlobalDebug == 1)
	{
//		alert("star"+this.IndicatorId+"_" + $star_number + " - " + $star.src);
//		alert($new_image);
	}

	if ($star.src != $new_image) {
		$star.src = $new_image;
	}
}

var GlobalDebug = 0;

RatingCollector.prototype.SetRatingStatus = function ($star_number, $active) {
	var $rating = $active ? $star_number : this.AvgRating;

	var $float_rating = Math.floor(($rating - Math.floor($rating)) / 0.5) * 0.5;
	var Dev;
	if (this.Debug == 1)
	{
		GlobalDebug = 1;
	}
	for (var $i = 1; $i <= 5; $i++) {
		if ($rating > $i - 1 && $rating < $i) {
			$active = $float_rating;
		}
		else {
			$active = $i <= $rating;
		}

		this.SetStarStatus($i, $active);
	}
	GlobalDebug = 0;
}


// Rating Collector
function RatingCollectorList($url, $avg_rating, $votes_counter_id, $voting_result_id, $already_voted, $IndicatorId, $TemplatesBase) {
	this.BusyRequest = false;
	this.URL = $url;
	this.AvgRating = parseFloat($avg_rating);
	this.IndicatorId = $IndicatorId;
	this.Debug = 0;
	this.AlreadyVoted = $already_voted;
	this.VotesCounterID = $votes_counter_id;
	this.VotingResultID = $voting_result_id;
	this.TemplatesBase = $TemplatesBase;
}

RatingCollectorList.prototype.successCallback = function($request, $params, $object) {
	var $responce = $request.responseText;
	var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
	if ($match_redirect != null) {
		// redirect to external template requested
		window.location.href = $match_redirect[1];
		return false;
	}

	var $rating = $responce.split('|');
	$object.AvgRating = parseFloat($rating[2]);
//	$object.AvgRating = parseFloat($rating[0]);
	$object.SetRatingStatus(0, 0);
	ospan = document.getElementById("votes_" + $object.IndicatorId);
	if (ospan) {
		ospan.innerHTML = $rating[1];	
	}
	$object.AlreadyVoted = true;

//	setTimeout( function () {$object.ClearVotingStatus(); }, 1500);
// 0 - avg question rating
// 1 - quiestion answers count
// 2 - current patients rating
// 3 - question asked patients rating
// 4 - doctor1 patients rating
// 5 - doctor2 patients rating
// 6 - doctor1 answers count
// 7 - doctor2 answers count
// 8 - doctor1 ID
// 9 - doctor2 ID
}

RatingCollectorList.prototype.ClearVotingStatus = function() {
	document.getElementById(this.VotingResultID).innerHTML = '';
}

RatingCollectorList.prototype.errorCallback = function($request, $params, $object) {
//	alert('AJAX Error; class: ClickCounter; ' + Request.getErrorHtml($request));
}

RatingCollectorList.prototype.SaveRating = function ($rating) {
	if (this.AlreadyVoted) {
		// don't process if already voted
		return ;
	}

	var $url = this.URL.replace('#RATING#', $rating);
	Request.headers = new Array();
	Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}

RatingCollectorList.prototype.SetStarStatus = function ($star_number, $active) {
	if (this.AlreadyVoted) {
		// don't process if already voted
		return ;
	}
	
	var $new_image = this.TemplatesBase + 'img/star_' + ($active ? (($active == 0.5) ? '0' : '1') : '2')  + '.gif';
	var $star = document.getElementById("star"+this.IndicatorId+"_" + $star_number);

	if (GlobalDebug == 1)
	{
//		alert("star"+this.IndicatorId+"_" + $star_number + " - " + $star.src);
//		alert($new_image);
	}

	if ($star.src != $new_image) {
		$star.src = $new_image;
	}
}

var GlobalDebug = 0;

RatingCollectorList.prototype.SetRatingStatus = function ($star_number, $active) {
	var $rating = $active ? $star_number : this.AvgRating;

	var $float_rating = Math.floor(($rating - Math.floor($rating)) / 0.5) * 0.5;
	var Dev;
	if (this.Debug == 1)
	{
		GlobalDebug = 1;
	}
	for (var $i = 1; $i <= 5; $i++) {
		if ($rating > $i - 1 && $rating < $i) {
			$active = $float_rating;
		}
		else {
			$active = $i <= $rating;
		}

		this.SetStarStatus($i, $active);
	}
	GlobalDebug = 0;
}



