Index: /trunk/calendar/inc/class.uicalendar.inc.php
===================================================================
--- /trunk/calendar/inc/class.uicalendar.inc.php	(revision 1126)
+++ /trunk/calendar/inc/class.uicalendar.inc.php	(revision 1447)
@@ -84,5 +84,6 @@
 			'footer' => True,
 			'css'		=> True,
-			'accounts_popup' => True
+			'accounts_popup' => True,
+			'disponibility' => True
 		);
 
@@ -1326,4 +1327,304 @@
 		}
 
+		function disponibility($params) {
+			
+			if(!isset($_SESSION['phpgw_info']['expresso']['expressoAdmin'])) {
+				$c = CreateObject('phpgwapi.config','expressoAdmin1_2');
+				$c->read_repository();
+				$current_config = $c->config_data;
+				
+				$ldap_manager = CreateObject('contactcenter.bo_ldap_manager');
+		
+				$_SESSION['phpgw_info']['expresso']['user'] = $GLOBALS['phpgw_info']['user'];
+				$_SESSION['phpgw_info']['expresso']['server'] = $GLOBALS['phpgw_info']['server'];
+				$_SESSION['phpgw_info']['expresso']['cc_ldap_server'] = $ldap_manager ? $ldap_manager->srcs[1] : null;
+				$_SESSION['phpgw_info']['expresso']['expressoAdmin'] = $current_config;
+				$_SESSION['phpgw_info']['expresso']['global_denied_users'] = $GLOBALS['phpgw_info']['server']['global_denied_users'];
+				$_SESSION['phpgw_info']['expresso']['global_denied_groups'] = $GLOBALS['phpgw_info']['server']['global_denied_groups'];
+			}
+			$str_participants = substr($_GET['participants'],0,strlen($_GET['participants'])-1); //remove the last comma
+			$participants= array();
+
+			$participants_splited = explode(",",$str_participants);
+			foreach($participants_splited as $participant) {
+				$participant = substr($participant,0,strlen($participant)-1);
+				$acct_type = $GLOBALS['phpgw']->accounts->get_type((int)$participant);
+				if($acct_type=='g') {
+					$bo_groups = CreateObject('expressoAdmin1_2.group');
+					$users = $bo_groups->get_info($participant);
+					foreach($users['memberuid_info'] as $user) {
+						if($user['type']==u)
+							$participants[$user['uidnumber']] = 'U';
+					}
+				}
+				else {
+					$participants[$participant] = 'U';
+				}
+			}
+			
+			$date = explode("/",$_GET['date']);
+			$freetime = $GLOBALS['phpgw']->datetime->localdates(mktime(0,0,0,$date[1],$date[0],$date[2]) - $GLOBALS['phpgw']->datetime->tz_offset);
+
+			echo $this->print_disponibility(
+				Array(
+					'date'		=> $freetime,
+					'starttime'	=> $this->bo->splittime('000000',False),
+					'endtime'	=> 0,
+					'participants'	=> $participants
+				)
+			);
+
+
+		}
+
+		function print_disponibility($param) {
+
+			$str = "<html><head>
+			<script type='text/javascript'>
+
+				var start = null;
+				var end = null;
+				function set_time(hour,minute) {
+					//alert(start);
+					if(start == null) {
+						start = new Array();
+						start[0] = hour;
+						start[1] = minute;
+						paint_interval(start,start,'#0000FF',true);
+					}
+					else if (end == null) {
+						end = new Array();
+						end[0] = hour;
+						end[1] = minute;
+						if(is_lower(start,end))
+							paint_interval(start,end,'#0000FF',true);
+						else {
+							paint_interval(end,start,'#0000FF',true);
+							temp = start;
+							start = end;
+							end = temp;
+							paint_interval(end,end,'#FFFFFF',false);
+						}
+						parent.document.getElementById('start_hour').value=start[0];
+						parent.document.getElementById('start_minute').value=start[1];				
+						parent.document.getElementById('end_hour').value=end[0];
+						parent.document.getElementById('end_minute').value=end[1];
+
+					}
+					else {
+						end = null;
+						start = new Array();
+						start[0] = hour;
+						start[1] = minute;
+						repaint();
+
+						paint_interval(start,start,'#0000FF',true);
+					}
+				}
+				function paint_column(name_array,color,force) {
+					name = name_array[0]+'-'+name_array[1];
+					if(navigator.userAgent.toLowerCase().indexOf('msie') == -1) {//firefox
+						for(var i in document.getElementsByName(name)) {
+							document.getElementsByName(name)[i].bgColor=color;
+							if(document.getElementsByName(name)[i].nodeType==1) {
+								if(document.getElementsByName(name)[i].innerHTML.indexOf('>-<')==-1 || force==true)
+									document.getElementsByName(name)[i].bgColor=color;
+								else
+									document.getElementsByName(name)[i].bgColor='".$this->theme['bg01']."';							
+							}
+						}
+					}
+					else {//I.E
+						cells = document.getElementsByTagName('td');
+						for(var i=0;i<cells.length;i++) {
+								if(cells.item(i).name==name) { //getElementsByName in I.E is bugged
+									cells.item(i).bgColor=color;
+									if(cells.item(i).nodeType==1) {
+										if(cells.item(i).innerHTML.indexOf('>-<')==-1 || force==true)
+											cells.item(i).bgColor=color;
+										else
+											cells.item(i).bgColor='".$this->theme['bg01']."';							
+								}
+							}
+						}
+					}
+				}
+				
+				function repaint() {
+					temp_start = new Array();
+					temp_start[0] = 8;
+					temp_start[1] = 0;
+					temp_end = new Array();
+					temp_end[0] = 19;
+					temp_end[1] = 0;
+					paint_interval(temp_start,temp_end,'#FFFFFF',false);
+				}
+				
+				//Considera sempre name1 <= name2
+				function paint_interval(name1,name2,color,force) {
+					paint_column(name1,color,force);
+					if(name1[0]!=name2[0] || name1[1]!=name2[1]) {
+						paint_column(name1,color,force);
+						tempHour = name1[0];
+						tempMinute = name1[1];
+						while(tempHour<name2[0]) {
+							if(tempHour==name1[0] && tempMinute!=0)
+								temp_start = tempMinute/30;
+							else
+								temp_start = 0;
+							for(i=temp_start;i<60/30;i++) {
+								temp_column = new Array();
+								temp_column[0] = tempHour;
+								temp_column[1] = i*30;
+								paint_column(temp_column,color,force);
+							}
+							tempHour++;
+						}
+						for(i=0;i<name2[1];i+=30) {
+							temp_column = new Array();
+							temp_column[0] = name2[0];
+							temp_column[1] = i;
+							paint_column(temp_column,color,force);
+						}
+					}
+				}
+				
+				function is_lower(array1,array2) {
+					if(array1[0]<array2[0])
+						return true;
+					else if(array1[0]>array2[0])
+						return false;
+					else {
+						if(array1[1]<array2[1])
+							return true;
+						else
+							return false;
+					}
+				}
+			</script></head><body>
+			";
+			
+			$str.= "<table border=\'1\' bgcolor=\"#FFFFFF\" width=\"100%\" height=\"100%\"><tr><td>";
+
+			
+			if(!is_array($param))
+			{
+				$this->index();
+			}
+
+			$date = $param['date'];
+			$starttime = $param['starttime'];
+			$endtime = $param['endtime'];
+			$participants = $param['participants'];
+			foreach($participants as $part => $nul)
+			{
+				$participants[$part] = $GLOBALS['phpgw']->common->grab_owner_name($part);
+				// Much better for processor  :)
+				$participants_id[]  .= $part;
+			}
+			uasort($participants,'strnatcasecmp');	// sort them after their fullname
+
+			if(!isset($this->bo->prefs['calendar']['interval']))
+			{
+				$this->bo->prefs['calendar']['interval'] = 15;
+				$GLOBALS['phpgw']->preferences->add('calendar','interval',15);
+				$GLOBALS['phpgw']->preferences->save_repository();
+			}
+			$increment = $this->bo->prefs['calendar']['interval'];
+			$interval = (int)(60 / $increment);
+
+			$pix = $GLOBALS['phpgw']->common->image('calendar','pix');
+
+			$str .= '<center>'.lang($GLOBALS['phpgw']->common->show_date($date['raw'],'l'))
+				. ', '.$this->bo->long_date($date).'<br>'
+				. '<table width="85%" border="0" cellspacing="0" cellpadding="0" cols="'.((10 * $interval) + 1).'">'
+				. '<tr><td height="1" colspan="'.((11 * $interval) + 1).'" bgcolor="black"><img src="'.$pix.'"></td></tr>'
+				. '<tr><td width="15%"><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.lang('Participant').'</font></td>';
+			for($i=8;$i<19;$i++)
+			{
+				for($j=0;$j<$interval;$j++)
+				{
+					$k = ($j == 0 ? sprintf('%02d',$i).'<br>':'').sprintf('%02d',$j*$increment);
+
+					$str .= '<td align="left" bgcolor="'.$this->theme['bg_color'].'" onclick="set_time('.$i.','.($j*$increment).')" style="cursor:hand;cursor:pointer">
+							<font color="'.$phpgw_info['theme']['bg_text'].'" face="'.$this->theme['font'].'" size="-2">' . $k."&nbsp;</font></td>\n";
+				}
+			}
+			$str .= '</tr>'
+				. '<tr><td height="1" colspan="'.((11 * $interval) + 1).'" bgcolor="black"><img src="'.$pix.'"></td></tr>';
+			if(!$endtime)
+			{
+				$endtime = $starttime;
+			}
+			$owner = $this->bo->owner;
+			foreach($participants as $part => $fullname)
+			{
+				$str .= '<tr align="center">'
+					. '<td width="15%" align="left"><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.$fullname.'</font></td>';
+
+				$this->bo->cached_events = Array();
+				$this->bo->so->owner = $part;
+				$this->bo->so->open_box($part);
+				$this->bo->store_to_cache(
+					Array(
+						'syear'	=> $date['year'],
+						'smonth'=> $date['month'],
+						'sday'	=> $date['day'],
+						'eyear'	=> 0,
+						'emonth'=> 0,
+						'eday'	=> $date['day'] + 1
+					)
+				);
+
+				if(!$this->bo->cached_events[$date['full']])
+				{
+					for($j=8;$j<19;$j++)
+					{
+						for($k=0;$k<$interval;$k++)
+						{
+//							$helper_name = $k*
+							$str .= '<td name="'.$j.'-'.($k*$increment).'" height="1" align="left" bgcolor="'.$this->theme['bg_color'].'" color="#999999">&nbsp;</td>';
+						}
+						$str .= "\n";
+					}
+				}
+				else
+				{
+					$time_slice = $this->bo->prepare_matrix($interval,$increment,$part,$date['full']);
+					for($h=8;$h<19;$h++)
+					{
+						$hour = $h * 10000;
+						for($m=0;$m<$interval;$m++)
+						{
+							$index = ($hour + (($m * $increment) * 100));
+							switch($time_slice[$index]['marker'])
+							{
+								case '&nbsp':
+									$time_slice[$index]['color'] = $this->theme['bg_color'];
+									//$extra = '';
+									break;
+								case '-':
+									$time_slice[$index]['color'] = $this->theme['bg01'];
+									$link = $this->page('view','&cal_id='.$time_slice[$index]['id'].'&date='.$date['full']);
+									//$extra =' title="'.$time_slice[$index]['description'].'" onClick="location.href=\''.$link.'\';" style="cursor:pointer; cursor:hand;"';
+									break;
+							}
+							$str .= '<td name="'.$h.'-'.($m*$increment).'" bgcolor="'.$time_slice[$index]['color'].'" color="#999999"><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.$time_slice[$index]['marker'].'</font></td>';
+						}
+						$str .= "\n";
+					}
+				}
+				$str .= '</tr>'
+					. '<tr><td height="1" colspan="'.((11 * $interval) + 1).'" bgcolor="#999999"><img src="'.$pix.'"></td></tr>';
+			}
+			$this->bo->owner = $owner;
+			$this->bo->so->owner = $owner;
+			$this->bo->so->open_box($owner);
+			$str.= "</table></center> \n </td></tr>
+			<tr><td onclick=\"parent.document.getElementById('disponibility').style.display='none'\" style='cursor:hand;cursor:pointer' align='center'>Fechar mapa</td></tr>
+			</table></body>";
+			return $str;
+		}
+
 		function day()
 		{
@@ -4472,5 +4773,5 @@
 			$var['starttime'] = Array(
 				'field'	=> lang('Start Time'),
-				'data'	=> '<input name="start[hour]" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($start,$hourformat).'" maxlength="2">:<input name="start[min]" size="2" value="'.$GLOBALS['phpgw']->common->show_date($start,'i').'" maxlength="2">'."\n".$str
+				'data'	=> '<input name="start[hour]" id="start_hour" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($start,$hourformat).'" maxlength="2">:<input name="start[min]" id="start_minute" size="2" value="'.$GLOBALS['phpgw']->common->show_date($start,'i').'" maxlength="2">'."\n".$str
 			);
 
@@ -4497,5 +4798,5 @@
 			$var['endtime'] = Array(
 				'field'	=> lang('End Time'),
-				'data'	=> '<input name="end[hour]" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($end,$hourformat).'" maxlength="2">:<input name="end[min]" size="2" value="'.$GLOBALS['phpgw']->common->show_date($end,'i').'" maxlength="2">'."\n".$str
+				'data'	=> '<input name="end[hour]" id="end_hour" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($end,$hourformat).'" maxlength="2">:<input name="end[min]" id="end_minute" size="2" value="'.$GLOBALS['phpgw']->common->show_date($end,'i').'" maxlength="2">'."\n".$str
 			);
 
@@ -4584,5 +4885,4 @@
 										</tr>
 										</table>
-									<script src='calendar/templates/".$_SESSION['phpgw_info']['calendar']['user']['preferences']['common']['template_set']."/js/edit.js' type='text/javascript'></script>
 									"
 						);
@@ -4634,6 +4934,12 @@
 								$var['participants'] = array
 								(
-									'field'	=> lang('Participants'),							
-									'data'	=> '<input type="hidden" id="txt_loading" value="'.lang("Loading").'">' .
+									'field'	=> '
+									<script src="calendar/templates/'.$_SESSION['phpgw_info']['calendar']['user']['preferences']['common']['template_set'].'/js/edit.js" type="text/javascript"></script><div id=\'disponibility\' style=\'display:none;position:absolute\' bgcolor=\'#FFFFFF\'>
+	<iframe src=\'#\' id=\'frame_disponibility\' width=\'500\' marginHeight=\'0\' marginWidth=\'0\'></iframe>
+</div>
+									'.lang('Participants'),							
+									'data'	=> '
+											<font color="#000088"><span onclick=\'show_disponibility()\' style="cursor:hand;cursor:pointer">Mapa de disponibilidade</span></font><br>
+											<input type="hidden" id="txt_loading" value="'.lang("Loading").'">' .
 											'<input type="hidden" id="txt_searching" value="'.lang("Searching").'">' .
 											'<input type="hidden" id="txt_users" value="'.lang("Users").'">' .							
Index: /trunk/calendar/templates/classic/js/edit.js
===================================================================
--- /trunk/calendar/templates/classic/js/edit.js	(revision 1267)
+++ /trunk/calendar/templates/classic/js/edit.js	(revision 1447)
@@ -50,5 +50,23 @@
 				select_in.options[i--] = null;																	
 	}
-													 									
+	function show_disponibility() {
+
+		participants = "";
+		combo = document.getElementById('user_list');
+		if(combo.length==0) {
+			alert('set the participants');
+			return;
+		}
+			
+		for (i=0;i<combo.length;i++) {
+			participants+=combo[i].value+",";
+		}
+		url = 'index.php?menuaction=calendar.uicalendar.disponibility&participants='+participants+'&date='+document.getElementById('start[str]').value;
+		
+		//alert(url);
+		document.getElementById('frame_disponibility').src = url;
+		document.getElementById('disponibility').style.display='';
+		//window.open(url);
+	}									 									
 	function submitValues(alert_msg){
 		var typeField = document.getElementById('cal[type]');
Index: /trunk/calendar/templates/default/js/edit.js
===================================================================
--- /trunk/calendar/templates/default/js/edit.js	(revision 1268)
+++ /trunk/calendar/templates/default/js/edit.js	(revision 1447)
@@ -43,5 +43,23 @@
 		oWait.innerHTML = '&nbsp;';
 	}			
-									
+	function show_disponibility() {
+
+		participants = "";
+		combo = document.getElementById('user_list');
+		if(combo.length==0) {
+			alert('set the participants');
+			return;
+		}
+			
+		for (i=0;i<combo.length;i++) {
+			participants+=combo[i].value+",";
+		}
+		url = 'index.php?menuaction=calendar.uicalendar.disponibility&participants='+participants+'&date='+document.getElementById('start[str]').value;
+		
+		//alert(url);
+		document.getElementById('frame_disponibility').src = url;
+		document.getElementById('disponibility').style.display='';
+		//window.open(url);
+	}					
 	function rem()
 	{
