Index: trunk/calendar/inc/class.ex_participants.inc.php
===================================================================
--- trunk/calendar/inc/class.ex_participants.inc.php	(revision 5143)
+++ trunk/calendar/inc/class.ex_participants.inc.php	(revision 5143)
@@ -0,0 +1,210 @@
+<?php
+    
+class exParticipants
+{
+    protected $participants = array();
+    var $lang;
+
+    function exParticipants($lang = false)
+    {
+       $this->lang = $lang;
+       if(!$this->lang['ACCEPTED']) $this->lang['ACCEPTED'] = 'Accepted';
+       if(!$this->lang['DECLINED']) $this->lang['DECLINED'] = 'Declined';
+       if(!$this->lang['TENTATIVE']) $this->lang['TENTATIVE'] = 'Tentative';
+       if(!$this->lang['DELEGATED']) $this->lang['DELEGATED'] = 'Delegated';
+       if(!$this->lang['NO ANSWER']) $this->lang['NO ANSWER'] = 'No answer';
+    }
+
+    function setParticipantsByString($pParticipants)
+    {
+        $arP = explode(',',trim($pParticipants));
+        
+        foreach($arP as $value)
+        {
+                $part = $this->parseParticipantString($value);
+                
+                if(empty($part)) continue;
+                
+                $this->participants[] = $part;
+
+        }
+    }
+
+    private function parseParticipantString($pParticipant)
+    {
+       $pParticipant = htmlspecialchars_decode($pParticipant);
+
+       $return = array();
+       
+       if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $pParticipant))
+       {
+          $cn = null;
+          $mail = null;
+          preg_match ("(\"([^\"]*)\")", $pParticipant, $cn);
+          preg_match ('(<([^>]*@[^>]*)>)', $pParticipant, $mail);
+
+          if($mail[1])
+          $return['mail'] =  $mail[1];
+
+          if($cn[1])
+            $return['cn'] =  $cn[1];
+
+          return $return;
+       }
+
+       if(preg_match("(<[^>]*@[^>]*>)", $pParticipant))
+       {
+          $mail = null;
+          preg_match ('(<([^>]*@[^>]*)>)', $pParticipant, $mail);
+          if($mail[1])
+            $return['mail'] =  $mail[1];
+          
+          return $return;
+       }
+
+       if(preg_match("([^ ]*@[^ ]*)", $pParticipant))
+       {
+          $mail = null;
+          preg_match ('([^ ]*@[^ ]*)', $pParticipant, $mail);
+          if($mail[0])
+            $return['mail'] =  $mail[0];
+          
+          return $return;
+       }
+       
+    }
+
+    function setParticipantsBySerializable($pParticipants)
+    {
+        
+       if(!unserialize(base64_decode($pParticipants))) //Compatibilidade com eventos antigos;
+           $this->setParticipantsByString($pParticipants);
+       else
+         $this->participants = unserialize(base64_decode($pParticipants));
+    }
+
+    function getParticipantsView()
+    {
+        $return = '';
+
+        $count = 0;
+        foreach($this->participants as $k => $v)
+        {
+            $exp = '';
+            
+            if($count > 0)
+                $exp .= '<br />';
+            
+            if($v['cn'])
+                $exp .= $v['cn'].' - ';
+
+            $exp .= $v['mail'].' ';
+
+            if($v['situation'])
+                $exp .= '('.$this->lang[$v['situation']].') ';
+            else
+                $exp .= '('.$this->lang['NO ANSWER'].')';
+
+            $count++;
+            $return .= $exp;
+        }
+
+        return $return;
+    }
+
+    function getParticipantsMailsString()
+    {
+        if(!$this->haveParticipants())
+            return '';
+        
+        $return = '';
+        
+        foreach($this->participants as $value)
+            $return .= $value['mail'].', ';
+
+        return (substr($return,0,-2));
+    }
+    
+    function getParticipantsSerializable()
+    {
+        return base64_encode(serialize($this->participants));
+    }
+    
+    function getParticipantsArray()
+    {
+        return $this->participants;
+    }
+    
+    function getParticipantsMailsArray()
+    {
+        $return = array();
+        
+        foreach ($this->participants as $value)
+                $return[] = $value['mail'];
+             
+        return $return;
+    }
+    
+    
+    function insertParticipant($pMail, $pSituation = false, $pCN = false)
+    {
+        $this->participants[]['mail'] = $pMail;
+        
+        if($pSituation)
+             $this->participants[]['situation'] = $pSituation;
+          
+        if($pCN)
+             $this->participants[]['cn'] = $pCN;
+    }
+    
+    function removeParticipant($pMail)
+    {
+        $mail = $this->parseParticipantString($pMail);
+        if(!empty($mail['mail']))
+            foreach($this->participants as $key => $value)
+                if($value['mail'] === $mail['mail'])
+                    unset($this->participants[$key]);
+    }
+
+    function updateAttribBySerializable($pParticipants)
+    {
+        $participans = unserialize(base64_decode($pParticipants));
+
+        foreach ($participans as $participant)
+        {
+            foreach($this->participants as $key => $value)
+            {
+                if($value['mail'] == $participant['mail'])
+                {
+                    $this->participants[$key]['cn'] = $participant['cn'];
+                    $this->participants[$key]['situation'] = $participant['situation'];
+                }
+            }
+        }
+
+    }
+
+    function updateParticipant($mail,$situation,$cn = false)
+    {
+        foreach($this->participants as $key => $value)
+        {
+            if(trim($value['mail']) == trim($mail))           
+            {
+                $this->participants[$key]['situation'] = $situation;
+                $this->participants[$key]['cn'] = $cn;
+            }
+        }
+    }
+    
+    function haveParticipants()
+    {
+        if(count($this->participants) > 0)
+            return true;
+        else
+            return false;
+    }
+
+
+
+}   
+?>
Index: trunk/calendar/templates/classic/js/edit_exmail.js
===================================================================
--- trunk/calendar/templates/classic/js/edit_exmail.js	(revision 5143)
+++ trunk/calendar/templates/classic/js/edit_exmail.js	(revision 5143)
@@ -0,0 +1,393 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** INCLUDE PARTICIPANTS - PLUGIN USING AJAX EXPRESSOMAIL COMPONENT  **|
+\******************************************************************************/
+var contacts = '';
+var expresso_offline = '';
+var array_lang = new Array();
+var finderTimeout = '';
+// onUnload edit message
+if(!document.all)
+{
+	var beforeunload = window.onbeforeunload;
+	window.onbeforeunload = function()
+	{
+		if ( typeof beforeunload == 'function' )
+			beforeunload();
+	};
+}
+	
+// Verifica versão do Firefox
+var agt = navigator.userAgent.toLowerCase();
+var is_firefox_0 = agt.indexOf('firefox/1.0') != -1 && agt.indexOf('firefox/0.') ? true : false;
+
+var handler_get_available_users = function(data)
+{	
+	select_available_users = Element('user_list_in');
+	
+	for(var i=0; i<select_available_users.options.length; i++){
+		select_available_users.options[i] = null;
+		i--;
+	}
+	var options = '###';
+	if (data) {
+		if(data.groups && data.groups.length > 0) {
+			data.groups = '<option  value="-1" disabled>------------------- '+Element("txt_groups").value+' ------------------ </option>' + data.groups;
+		}		
+		if(data.users && data.users.length > 0) {
+			data.users = '<option  value="-1" disabled>------------------- '+Element("txt_users").value+' ------------------ </option>' + data.users;
+		}
+		options +=  data.groups && data.groups.length > 0 ? data.groups : '';
+		options +=  data.users  && data.users.length  > 0 ? data.users  : '';
+		
+		if(is_firefox_0)
+			fixBugInnerSelect(select_available_users,options);
+		else
+			select_available_users.innerHTML = options;
+
+		select_available_users.outerHTML = select_available_users.outerHTML;
+		select_available_users.disabled = false;
+		select_available_users_clone = Element('user_list_in').cloneNode(true);		
+	}
+}	
+
+function get_available_users(module,context,type, autoSearch){
+	Element('cal_input_searchUser').value = '';
+	if(autoSearch != 'True'){
+		return true;
+	}
+	var context = document.getElementById('combo_org').value;	
+	cExecute (module+'.ldap_functions.get_available_users&context='+context+'&type='+type, handler_get_available_users);
+}
+
+function optionFinderTimeout(obj, numMin, type, autoSearch){
+	var oWait = Element("cal_span_searching");
+	oWait.innerHTML = 'Buscando...';
+	clearTimeout(finderTimeout);		
+	
+	if(autoSearch == "True"){
+		finderTimeout = setTimeout("optionFinderLocal('"+obj.id+"')",500);
+	}
+	else if (obj.value.length >= numMin){
+		finderTimeout = setTimeout("optionFinderLdap('"+obj.id+"','"+numMin+"','"+type+"')",500);
+	}else {
+		oWait.innerHTML = 'Mínimo de '+numMin+' letras para pesquisa';
+		var select_available_users_tmp = document.getElementById('user_list_in');
+		for(var i = 0;i < select_available_users_tmp.options.length; i++)
+		select_available_users_tmp.options[i--] = null;
+	}
+}
+// Pesquisa Javascript
+function optionFinderLocal(id){
+	var oText = Element(id);
+	var oWait = Element("cal_span_searching");
+	var select_available_users_tmp = Element('user_list_in');
+	for(var i = 0;i < select_available_users_tmp.options.length; i++)
+		select_available_users_tmp.options[i--] = null;
+	var RegExp_name = new RegExp("\\b"+oText.value, "i");
+
+	for(i = 0; i < select_available_users_clone.length; i++){
+		if (RegExp_name.test(select_available_users_clone[i].text) || select_available_users_clone[i].value =="-1")
+		{
+			sel = select_available_users_tmp.options;
+			option = new Option(select_available_users_clone[i].text,select_available_users_clone[i].value);
+			if( select_available_users_clone[i].value == "-1") option.disabled = true;
+			sel[sel.length] = option;
+		}
+	}
+	oWait.innerHTML = '&nbsp;';	
+}
+
+// Pesquisa LDAP
+function optionFinderLdap(id,numMin, type){
+		var oWait = Element("cal_span_searching");
+		var oText = Element(id);
+			
+		if (oText.value.length < numMin) {
+				oWait.innerHTML = '';
+				var select_available_users_tmp = document.getElementById('user_list_in');
+				for(var i = 0;i < select_available_users_tmp.options.length; i++)
+					select_available_users_tmp.options[i--] = null;
+		}
+		
+		if (oText.value.length >= numMin){
+			var context = document.getElementById('combo_org').value;
+			cExecute ('expressoMail1_2.ldap_functions.search_users&context='+(context)+'&type='+(type == '' ? 'list' : 'search')+'&filter='+oText.value, handler_get_available_users);
+			oWait.innerHTML = '&nbsp;';
+		}
+}
+
+function add_user()
+{
+	var select_available_users = document.getElementById('user_list_in');
+	var select_users = document.getElementById('user_list');
+	var count_available_users = select_available_users.length;
+	var count_users = select_users.options.length;
+	var new_options = '';
+	
+	for (i = 0 ; i < count_available_users ; i++) {
+		if (select_available_users.options[i].selected)	{
+			if(document.all) {
+				if ( (select_users.innerHTML.indexOf('value='+select_available_users.options[i].value)) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+				}
+			}
+			else if ( (select_users.innerHTML.indexOf('value="'+select_available_users.options[i].value+'"')) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+			}
+		}
+	}
+
+	if (new_options != '') {
+
+		if(is_firefox_0)
+			fixBugInnerSelect(select_users,'###' + new_options + select_users.innerHTML);
+		else
+			select_users.innerHTML = '###' + new_options + select_users.innerHTML;
+
+		select_users.outerHTML = select_users.outerHTML;
+	}
+}
+
+function remove_user(){
+	select_users = document.getElementById('user_list');
+	
+	for(var i = 0;i < select_users.options.length; i++)
+		if(select_users.options[i].selected)
+			select_users.options[i--] = null;
+}
+
+function submitValues(){
+	var typeField = document.getElementById('cal[type]');
+	if (typeField && typeField.value == 'hourAppointment') {
+		if(document.getElementsByName('categories[]')[0].value == ""){
+			alert(alert_msg);
+			return false;
+		}
+	}
+	var select_in = document.getElementById('user_list');
+	for(i = 0; i < select_in.length; i++)
+	 	select_in.options[i].selected = true;
+}	
+
+function Element(id){
+	return document.getElementById(id);
+}
+
+function loadScript(scriptPath){
+
+	if(!connector)
+		throw new Error("Error : Connector is not loaded.");
+		
+  	if (document.getElementById('uploadscript_'+scriptPath)) {
+  		return;
+   	}
+  	
+	connector.oxmlhttp.open("GET", scriptPath, false);
+    connector.oxmlhttp.setRequestHeader('Content-Type','text/plain');
+	connector.oxmlhttp.send(null);
+	if(connector.oxmlhttp.status != 0 && connector.oxmlhttp.status != 200 || 	connector.oxmlhttp.status == 0 && connector.oxmlhttp.responseText.length == 0)
+		throw new Error("Error " + connector.oxmlhttp.status + "("+connector.oxmlhttp.statusText+") when loading script file '"+scriptPath+"'");
+	
+	var head = document.getElementsByTagName("head")[0];
+	var script = document.createElement("SCRIPT");
+	script.id = 'uploadscript_'+scriptPath;
+	script.type = 'text/javascript';		
+	script.text = connector.oxmlhttp.responseText;
+	head.appendChild(script);
+	return;	
+}
+
+function showExParticipants(el,path){
+	Element('tbl_ext_participants').style.display='';
+	el.style.display='none';
+	loadScript(path+"/js/DropDownContacts.js");
+	loadScript(path+"/js/common_functions.js");
+	loadScript(path+"/js/QuickCatalogSearch.js");
+	loadScript("calendar/templates/classic/js/over_fn_exmail.js");
+	if(!contacts)
+		cExecute (path+'.db_functions.get_dropdown_contacts', save_contacts);
+}
+
+function hideExParticipants(el,path){
+	Element('a_ext_participants').style.display = '';
+	Element('tbl_ext_participants').style.display ='none';
+}
+
+function save_contacts(data){
+	contacts = data;	
+	var input_to = Element("ex_participants");
+	input_to.style.width = "100%";
+	input_to.setAttribute("wrap","soft");	
+	input_to.onfocus = function(){clearTimeout(parseInt(setTimeOutLayer)); search_contacts('onfocus', this.id);};
+	input_to.onblur = function(){setTimeOutLayer=setTimeout('search_contacts("lostfocus","'+this.id+'")',100);};
+	if (!is_ie)
+	{
+		input_to.rows = 2;
+		input_to.onkeypress = function (e)
+		{
+			if ((e.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				if (((e.keyCode == 13) || ((e.keyCode == 38)||(e.keyCode == 40))) && (document.getElementById('tipDiv').style.visibility!='hidden'))
+				{
+					e.preventDefault();
+					search_contacts(e.keyCode,this.id);
+				}
+			}
+		}
+		input_to.onkeyup = function (e)
+		{
+			if ((e.keyCode != 13) && (e.keyCode != 38) && (e.keyCode != 40))
+			{
+				search_contacts(e.keyCode,this.id);
+			}
+		}
+	}
+	else
+	{
+		input_to.rows = 3;
+		input_to.onkeyup = function (e)
+		{
+			if ((window.event.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				search_contacts(window.event.keyCode,this.id);
+			}	
+		}
+	}
+}
+
+function fixBugInnerSelect(objeto,innerHTML){
+/******
+* select_innerHTML - altera o innerHTML de um select independente se é FF ou IE
+* Corrige o problema de não ser possível usar o innerHTML no IE corretamente
+* Veja o problema em: http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
+* Use a vontade mas coloque meu nome nos créditos. Dúvidas, me mande um email.
+* Versão: 1.0 - 06/04/2006
+* Autor: Micox - Náiron José C. Guimarães - micoxjcg@yahoo.com.br
+* Parametros:
+* objeto(tipo object): o select a ser alterado
+* innerHTML(tipo string): o novo valor do innerHTML
+*******/
+    objeto.innerHTML = ""
+    var selTemp = document.createElement("micoxselect")
+    var opt;
+    selTemp.id="micoxselect1"
+    document.body.appendChild(selTemp)
+    selTemp = document.getElementById("micoxselect1")
+    selTemp.style.display="none"
+    if(innerHTML.toLowerCase().indexOf("<option")<0){//se não é option eu converto
+        innerHTML = "<option>" + innerHTML + "</option>"
+    }
+    innerHTML = innerHTML.replace(/<option/g,"<span").replace(/<\/option/g,"</span")
+    selTemp.innerHTML = innerHTML
+    for(var i=0;i<selTemp.childNodes.length;i++){
+        if(selTemp.childNodes[i].tagName){
+            opt = document.createElement("OPTION")
+            for(var j=0;j<selTemp.childNodes[i].attributes.length;j++){
+                opt.setAttributeNode(selTemp.childNodes[i].attributes[j].cloneNode(true))
+            }
+            opt.value = selTemp.childNodes[i].getAttribute("value")
+            opt.text = selTemp.childNodes[i].innerHTML
+            if(document.all){ //IEca
+                objeto.add(opt)
+            }else{
+                objeto.appendChild(opt)
+            }                    
+        }    
+    }
+    document.body.removeChild(selTemp)
+    selTemp = null
+}
+
+function changeViewMode(eltype){
+	var chValue = eltype;
+	switch (chValue){
+		case 'hourAppointment':
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "none";
+			}
+
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			Field[1].parentNode.parentNode.style.display = "none";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "none";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			break;
+		case 'privateHiddenFields':
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "";
+			}
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			Field[1].parentNode.parentNode.style.display = "none";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "none";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "";
+			break;
+		default:
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "";
+			}
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "";
+			Field[1].parentNode.parentNode.style.display = "";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "";
+			break;
+	}
+
+}
+function updateTitleField(select){
+	var typeField = document.getElementsByName('cal[type]');
+	if (typeField[0].value != 'hourAppointment')
+		return;
+	var titleField = document.getElementsByName('cal[title]');
+	var optionsArray = select.childNodes;
+	titleField[0].value = '';
+	for(option in optionsArray)
+		if (optionsArray[option].selected)
+			titleField[0].value += optionsArray[option].text + ' ';
+}
+
+var __onLoad = window.onload;
+window.onload = function(){ 
+	__onLoad();
+	var cal_type = document.getElementById('cal[type]').value;
+	changeViewMode(cal_type);
+	if(cal_type == 'hourAppointment'){
+		clearTimeout(timeout_get_available_users);
+	}
+};
Index: trunk/calendar/templates/classic/js/edit.js
===================================================================
--- trunk/calendar/templates/classic/js/edit.js	(revision 5143)
+++ trunk/calendar/templates/classic/js/edit.js	(revision 5143)
@@ -0,0 +1,123 @@
+/******************************************************************************\
+|**************************   MODULO   AGENDA   *******************************|
+|********** SCRIPT REFERENTE A CAIXA DE INCLUSAO DE PARTICIPANTES  ************|
+\******************************************************************************/
+
+// Variaveis Locais 
+	var select_in  = document.getElementById('user_list');
+	var select_out  = document.getElementById('user_list_in');	
+	var users_out = select_out ? select_out.cloneNode(true) : '';
+	var finderTimeout = '';
+																		
+// Funcoes				
+	function showExParticipants(el,path){
+		document.getElementById('tbl_ext_participants').style.display='';
+		el.style.display='none';
+	}
+	
+	function hideExParticipants(el,path){
+		document.getElementById('a_ext_participants').style.display = '';
+		document.getElementById('tbl_ext_participants').style.display ='none';
+	}
+							
+	function optionFinderTimeout(obj){
+
+		clearTimeout(finderTimeout);	
+		var oWait = document.getElementById("wait");
+		oWait.innerHTML = 'Buscando...';
+		finderTimeout = setTimeout("optionFinder('"+obj.id+"')",500);
+	}
+	function optionFinder(id) {	
+		var oWait = document.getElementById("wait");
+		var oText = document.getElementById(id);
+		for(var i = 0;i < select_out.options.length; i++)				
+			select_out.options[i--] = null;
+																							
+		for(i = 0; i < users_out.length; i++){																							
+			if(users_out[i].text.substring(0 ,oText.value.length).toUpperCase() == oText.value.toUpperCase()) {
+				sel = select_out.options;						
+				option = new Option(users_out[i].text,users_out[i].value);				
+				sel[sel.length] = option;
+			}
+		}
+		oWait.innerHTML = '&nbsp;';
+	}			
+									
+	function rem()
+	{
+		for(var i = 0;i < select_in.options.length; i++)				
+			if(select_in.options[i].selected)
+				select_in.options[i--] = null;																	
+	}
+		
+	function submitValues(alert_msg){
+		var typeField = document.getElementById('cal[type]');
+		if (typeField && typeField.value == 'hourAppointment')
+			if(document.getElementsByName('categories[]')[0].value == ""){
+				alert(alert_msg);
+				return false;
+				}
+		for(i = 0; i < select_in.length; i++)
+		 	select_in.options[i].selected = true;
+	}
+	
+		
+    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 openListUsers(newWidth,newHeight, owner){					
+		newScreenX  = screen.width - newWidth;		
+		newScreenY  = 0;		
+		window.open('calendar/templates/classic/listUsers.php?owner='+owner,"","width="+newWidth+",height="+newHeight+",screenX="+newScreenX+",left="+newScreenX+",screenY="+newScreenY+",top="+newScreenY+",toolbar=no,scrollbars=yes,resizable=no");
+	}
+
+ 	function adicionaListaCalendar() 
+ 	{
+		var select = window.document.getElementById('user_list_in');
+		var selectOpener = window.opener.document.getElementById('user_list');
+		for (i = 0 ; i < select.length ; i++) {				
+
+			if (select.options[i].selected) {
+				isSelected = false;
+
+				for(var j = 0;j < selectOpener.options.length; j++) {																			
+					if(selectOpener.options[j].value == select.options[i].value){
+						isSelected = true;						
+						break;	
+					}
+				}
+
+				if(!isSelected){
+
+					option = window.opener.document.createElement('option');
+					option.value =select.options[i].value;
+					option.text = select.options[i].text;
+					selectOpener.options[selectOpener.options.length] = option;	
+				}
+				
+			}
+		}
+		selectOpener.options[selectOpener.options.length-1].selected = true;
+ 	}
+	
+// Fim        
Index: trunk/calendar/templates/classic/js/search.js
===================================================================
--- trunk/calendar/templates/classic/js/search.js	(revision 5143)
+++ trunk/calendar/templates/classic/js/search.js	(revision 5143)
@@ -0,0 +1,108 @@
+var searchTimeout;
+
+function lang(key){
+	return document.getElementById("txt_"+key).value;
+}
+
+function remove_user(id){
+	if(!confirm(lang("confirm")))
+		return true;	
+	var handler_rem_user = function(data){
+		if(data) {
+			var tr = document.getElementById(id);
+			tr.parentNode.removeChild(tr);
+		}
+	}	
+	cExecute ('calendar.uigroup_access.rem_user&id='+id, handler_rem_user);
+}
+function add_user(){
+	var select_users = document.getElementById("user");
+	var select_groups = document.getElementById("group");
+	var a_rights = new Array("L","A","E","R","P");
+	var rights = '';
+	for(var z = 0; z < a_rights.length; z++){
+		var check = document.getElementById("right_"+a_rights[z]);
+		if(check.checked){
+			rights += check.value;
+		}
+	}
+	if(!select_users.value){
+		alert(lang("nouser"));
+		return;
+	}
+	else if(!select_groups.value){
+		alert(lang("nogroup"));
+		return;
+	}
+	else if(!rights){
+		alert(lang("nopermissiontype"));
+		return;
+	}
+	
+	var str = select_users.value+";"+select_groups.value;
+	var handler_add_user = function(data){
+		
+		if(data){
+			var t = document.getElementById('tbody_list');
+			var tr = document.createElement("TR");
+			tr.bgColor = "#DCDCDC";
+			var td1 = document.createElement("TD");
+			var td2 = document.createElement("TD");
+			var td3 = document.createElement("TD");
+			var td4 = document.createElement("TD");
+			tr.id = str;
+			td1.innerHTML = "<b>&nbsp;&nbsp;"+select_users[select_users.selectedIndex].text+"</b>";
+			td2.innerHTML = rights;
+			td2.align = "center";
+			td3.innerHTML = "&nbsp;&nbsp;"+select_groups[select_groups.selectedIndex].text;
+			td4.innerHTML = "<button  title='remove' type='button' onClick='javascript:remove_user(\""+str+"\");'><img src='"+document.getElementById("template_set").value+"/images/delete.png' style='vertical-align: middle;'/></button>";
+			tr.appendChild(td1);
+			tr.appendChild(td2);
+			tr.appendChild(td3);
+			tr.appendChild(td4);
+			t.appendChild(tr);
+			alert(lang("success"));
+		}
+		else{
+			alert(lang("exist"));
+		}
+	}
+	cExecute ('calendar.uigroup_access.add_user&id='+str+"&rights="+rights, handler_add_user);
+	return true;
+		
+}
+function search_object(input, id_span, id_select, type)
+{
+	clearTimeout(searchTimeout);	
+	var spam = document.getElementById(id_span);
+	if (input.value.length <= 3){
+		spam.innerHTML = lang("typemoreletters").replace("X",4 - input.value.length);
+	}else{
+		spam.innerHTML = lang("searching")+'...';
+		searchTimeout = setTimeout("search_ldap('"+input.id+"','"+id_span+"','"+id_select+"','"+type+"')",750);
+	}
+}
+
+function search_ldap(id_input, id_span, id_select, type)
+{
+	var search = document.getElementById(id_input).value;
+	
+	var handler_search_user = function(data)
+	{
+		var spam = document.getElementById(id_span);
+		select_available_users = document.getElementById(id_select);
+		if (data.status == 'false')
+		{
+			spam.innerHTML = data.msg;
+			// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+			select_available_users.innerHTML = '#';
+			select_available_users.outerHTML = select_available_users.outerHTML;
+			return;
+		}	
+		spam.innerHTML = '';
+		// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+		select_available_users.innerHTML = '#' + data;
+		select_available_users.outerHTML = select_available_users.outerHTML;
+	}
+	cExecute ('calendar.uigroup_access.search_user&search='+search+"&type="+type, handler_search_user);
+}
Index: trunk/calendar/templates/classic/js/over_fn_exmail.js
===================================================================
--- trunk/calendar/templates/classic/js/over_fn_exmail.js	(revision 5143)
+++ trunk/calendar/templates/classic/js/over_fn_exmail.js	(revision 5143)
@@ -0,0 +1,163 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** PLUGIN USING AJAX EXPRESSOMAIL COMPONENT - OVERWRITE FUNCTIONS   **|
+\******************************************************************************/
+
+/******************************************************************************\
+|** Function      : emQuickSearch *********************************************|
+|** Original File : <expressoMail_module>/js/common_functions.js **************|
+\******************************************************************************/
+window.onresize = function(){};
+function emQuickSearch(el){
+
+	var emailList = el.value;
+	var field = el.id;
+	var ex_participants = Element("ex_participants");
+	var quickSearchKeyBegin;
+	var quickSearchKeyEnd;
+	
+	var handler_emQuickSearch = function(data){
+		window_DropDownContacts = Element('tipDiv');
+		if (window_DropDownContacts.style.visibility != 'hidden'){
+			window_DropDownContacts.style.visibility = 'hidden';
+		}
+		
+		if ((!data.status) && (data.error == "many results")){
+			alert(get_lang('More than %1 results. Please, try to refine your search.',200));
+			return false;
+		}
+			
+		if (data.length > 0){
+			QuickCatalogSearch.showList(data, quickSearchKeyBegin, quickSearchKeyEnd);
+		}
+		else
+			alert(get_lang('None result was found.'));
+		return true;
+	}
+	ex_participants.focus(); 				//mecessary for IE.
+	var i = getPosition(ex_participants); //inputBox.selectionStart;
+	var j = --i;
+
+    while ((j >= 0) && (emailList.charAt(j) != ',')){j--};
+    quickSearchKeyBegin = ++j;
+
+    while ((i <= emailList.length) && (emailList.charAt(i) != ',')){i++};
+    quickSearchKeyEnd = i;
+
+    var search_for = trim(emailList.substring(quickSearchKeyBegin, quickSearchKeyEnd));
+
+	if (search_for.length < 4){
+		alert(get_lang('Your search argument must be longer than 4 characters.'));
+		return false;
+	}
+	
+	cExecute ("expressoMail1_2.ldap_functions.quicksearch&search_for="+search_for+"&field="+field, handler_emQuickSearch);
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.transfer_result ************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.transfer_result = function (field, ID, begin, end){
+	cm = document.getElementById('select_QuickCatalogSearch');
+	option_selected = cm.options[cm.selectedIndex].value + ", ";
+	emailList = Element("ex_participants").value;		
+	new_emailList = emailList.substring(0, begin) + option_selected + emailList.substring((parseInt(end) + 2), emailList.length);
+	document.getElementById("ex_participants").value = new_emailList;
+	if(is_ie)
+		Element("i_blank").style.display = "none";
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.close_QuickSearch_window ***|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.close_QuickSearch_window = function (field, ID){
+	if(is_ie)
+		Element("i_blank").style.display = "none";
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.showWindow *****************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.showWindow = function (div)
+{
+	if(! div) {
+		alert(get_lang('The list has no participant.'));
+		return;
+	}
+						
+	if(! this.arrayWin[div.id]) {
+		div.style.width = "700px";
+		div.style.height = "230px";
+		var title = get_lang('The results were found in the Global Catalog')+':';
+		var wHeight = div.offsetHeight + "px";
+		var wWidth =  div.offsetWidth   + "px";
+		div.style.width = div.offsetWidth - 5;
+
+		win = new dJSWin({			
+			id: 'QuickCatalogSearch_'+div.id,
+			content_id: div.id,
+			width: wWidth,
+			height: wHeight,
+			y:'300px',
+			top: '300px',
+			title_color: '#3978d6',
+			bg_color: '#eee',
+			title: title,						
+			title_text_color: 'white',
+			button_x_img: 'phpgwapi/images/winclose.gif',
+			border: true });
+		
+		this.arrayWin[div.id] = win;
+		win.draw();
+	}
+	else {
+		win = this.arrayWin[div.id];
+	}
+
+	if(is_ie) {	
+		var _IFrame = Element("i_blank");
+		if(_IFrame){
+    		_IFrame.style.display  = '' ;		
+		}
+		else {
+			_IFrame = document.body.appendChild(document.createElement('iframe'));
+			_IFrame.src = 'about:blank' ;
+		    _IFrame.frameBorder		= '0';
+		    _IFrame.scrolling		= 'no' ;
+		    _IFrame.style.left		= findPosX(div)  + document.body.scrollLeft -5;
+			_IFrame.style.top		= findPosY(div)  + document.body.scrollTop  -20;
+		    _IFrame.width			= 610;
+   		    _IFrame.style.border	= 0;
+			_IFrame.height			= 285;
+			_IFrame.border			= 0;
+			_IFrame.id				= "i_blank";
+		    _IFrame.style.position	= 'absolute';
+	   	    _IFrame.style.zIndex	= '5';
+    		_IFrame.style.display  = '' ;
+		}
+	}
+
+	win.open();
+	document.getElementById('select_QuickCatalogSearch').focus();
+}	
+
+
+/******************************************************************************\
+|** Function      :  DRAG *****************************************************|
+|** Original File : phpgwapi/js/wz_dragdrop/wz_dragdrop.js ********************|
+\******************************************************************************/
+var over_fn_DRAG = DRAG;
+DRAG = function (event){
+
+		if(is_ie)
+			return false;
+		else
+			over_fn_DRAG(event);
+}		
Index: trunk/calendar/templates/default/suggestion.tpl
===================================================================
--- trunk/calendar/templates/default/suggestion.tpl	(revision 5143)
+++ trunk/calendar/templates/default/suggestion.tpl	(revision 5143)
@@ -0,0 +1,90 @@
+<div id="suggestion" style="visibility: hidden; display: none;">
+<!-- BEGIN list -->
+	<link rel="stylesheet" type="text/css" href="phpgwapi/templates/default/css/base.css" />
+	<link rel="stylesheet" type="text/css" href="phpgwapi/templates/default/css/azul.css" />
+	<link rel="stylesheet" type="text/css" href="phpgwapi/templates/default/css/modal.css" />
+	<style>
+	.inputDate {
+		width: 60px;
+	}
+	
+	.inputTime {
+		width: 20px;
+	}
+	
+	#line3 div{
+		margin-top:10px;
+		margin-bottom:10px;
+		text-align:center;
+		width: 60px;
+	}	
+	
+	#divAppBox  {
+		padding: 1px;
+	}
+	
+	</style>
+	<title> {lang_suggest_new_hour} - Expresso </title>
+	<script src="{url}/calendar/templates/default/js/suggestion.js" type="text/javascript"></script>
+	<link rel="stylesheet" type="text/css" media="all" href="{url}/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css" title="" />
+	<script type="text/javascript" src="{url}/phpgwapi/js/jscalendar/calendar.js"></script>
+	<script type="text/javascript" src="{url}/phpgwapi/inc/jscalendar-setup.php"></script>
+	<form action="{action_form}&cal_id={cal_id};{to};{title};{description};{uid};{location};{ex_participants};{user}" method="post" autocomplete="off">
+		<div class="popup modal" style="margin-left:410px; margin-right: 410px; padding: 20px">
+			<h1 id="divAppboxHeader" class="title">{notify_message}</h1>
+			<div id="divAppbox" class="body">
+				<ul class="fields">
+					<li id="line1" class="even">
+						<div class="fieldCell"><label>{lang_start_date}</label>
+							<input type="text" class="inputDate" id="data_inicio" name="data_inicio" value="{start_date}" onBlur="javascript:validate_date_field(this,0);" onkeyup="javascript:insere_barras(0);">
+								<link rel="stylesheet" type="text/css" media="all" href="{url}/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css" title="" />
+								<script type="text/javascript" src="{url}/phpgwapi/js/jscalendar/calendar.js"></script>
+								<script type="text/javascript" src="{url}/phpgwapi/inc/jscalendar-setup.php"></script>
+							<script type="text/javascript">
+								document.writeln('<img id="data_inicio-trigger" src="{url}/phpgwapi/templates/default/images/datepopup.gif" title="Selecionar data" style="cursor:pointer; cursor:hand;"/>');
+								Calendar.setup(
+								{
+									inputField : "data_inicio",
+									button : "data_inicio-trigger"
+								}
+								); 
+							</script>
+							
+						</div>
+						<div class="fieldCell"><label>{lang_start_hour}</label>
+							<input type="text" class="inputTime" id="hora_inicio" name="hora_inicio" value="{start_hour}" onBlur="javascript:validate_hour_field(this,0);">
+							:
+							<input type="text" class="inputTime" id="minuto_inicio" name="minuto_inicio" value="{start_minute}" onBlur="javascript:validate_minute_field(minuto_inicio,0);">	
+						</div>
+					</li>
+					<li id="line2" class="odd">
+						<div class="fieldCell"><label>{lang_end_date}</label>
+							<input type="text" class="inputDate" id="data_final" name="data_final" value="{end_date}" onBlur="javascript:validate_date_field(this,1);" onkeyup="javascript:insere_barras(1);">
+						
+							<script type="text/javascript">
+								document.writeln('<img id="data_final-trigger" src="{url}/phpgwapi/templates/default/images/datepopup.gif" title="Selecionar data" style="cursor:pointer; cursor:hand;"/>');
+								Calendar.setup(
+								{
+									inputField : "data_final",
+									button : "data_final-trigger"
+								}
+								); 
+							</script>
+							
+						</div>
+						<div class="fieldCell"><label>{lang_end_hour}</label>
+						<input type="text" class="inputTime "id="hora_final" name="hora_final" value="{end_hour}" onBlur="javascript:validate_hour_field(this,1);">
+						:
+						<input type="text" class="inputTime "id="minuto_final" name="minuto_final" value="{end_minute}" onBlur="javascript:validate_minute_field(minuto_final,1);">
+						</div>
+					</li>
+					<li id="line3" class="even">
+						<div class="fieldCell"><input type="button" value="Cancelar" onclick="javascript:fecha_sugestao();"></div>
+						<div class="fieldCell"><input type="submit" value="Sugerir" onClick='return trata_botao_submit();'></div>
+					</li>
+				</ul>
+			</div>
+		</div>
+	</form>
+    <!-- END list -->
+</div>
Index: trunk/calendar/templates/default/js/edit_exmail.js
===================================================================
--- trunk/calendar/templates/default/js/edit_exmail.js	(revision 5143)
+++ trunk/calendar/templates/default/js/edit_exmail.js	(revision 5143)
@@ -0,0 +1,515 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** INCLUDE PARTICIPANTS - PLUGIN USING AJAX EXPRESSOMAIL COMPONENT  **|
+\******************************************************************************/
+var contacts = '';
+var expresso_offline = '';
+var array_lang = new Array();
+var finderTimeout = '';
+// onUnload edit message
+if(!document.all)
+{
+	var beforeunload = window.onbeforeunload;
+	window.onbeforeunload = function()
+	{
+		if ( typeof beforeunload == 'function' )
+			beforeunload();
+	};
+}
+	
+// Verifica versão do Firefox
+var agt = navigator.userAgent.toLowerCase();
+var is_firefox_0 = agt.indexOf('firefox/1.0') != -1 && agt.indexOf('firefox/0.') ? true : false;
+
+var handler_get_available_users = function(fill)
+{	
+	var groupHandler = function( toGroup )
+	{
+	    switch( toGroup[ 'phpgwaccounttype' ] )
+	    {
+		case 'u':return 'users';
+		break;
+		case 'g':return 'groups';
+		break;
+                case 's':return 'shared_accounts';
+                break
+	    }
+
+	    return( false );
+	}
+
+	return fillGroupableSelect( fill, 'user_list_in', groupHandler, default_field );
+}	
+
+function get_available_users(module,context,type, autoSearch){
+// 	Element('cal_input_searchUser').value = '';
+// 	if(autoSearch != 'True'){
+// 		return true;
+// 	}
+// 	var context = document.getElementById('combo_org').value;	
+// 	cExecute (module+'.ldap_functions.get_available_users&context='+context+'&type='+type, handler_get_available_users);
+}
+
+function optionFinderTimeout(obj, numMin, type, autoSearch, event){
+
+	if( event.keyCode === 13 )
+	{
+	    //limit = 0;
+
+	    optionFinderLdap( obj.id, numMin, type );
+
+	    return( false );
+	}
+
+	return( true );
+}
+// Pesquisa Javascript
+function optionFinderLocal(id){
+
+	var sentence = Element( id ).value;
+
+	finder( sentence, 'user_list_in' );
+}
+
+// Pesquisa LDAP
+function optionFinderLdap(id,numMin, type){
+
+	var sentence = Element( id ).value;
+
+	var url = 'expressoMail1_2.ldap_functions.search_users&context=' + document.getElementById('combo_org').value + '&type='+(type == '' ? 'list' : 'search')+'&filter=' + sentence;
+	
+	var parser = function( data ){
+
+	    var result = {};
+
+	    for( accountType in data )
+	    {
+		var target = data[ accountType ];
+
+		accountType = accountType.charAt(0);
+
+		for( value in target )
+		{
+		    result[value] = {};
+		    result[value][default_field] = target[value];
+		    result[value]['phpgwaccounttype'] = accountType;
+		}
+
+	    }
+
+	    return( result );
+	};
+
+	return userFinder( sentence, handler_get_available_users, url, parser, 'cal_span_searching' );
+}
+
+function add_user()
+{
+	var select_available_users = document.getElementById('user_list_in');
+	var select_users = document.getElementById('user_list');
+	var count_available_users = select_available_users.length;
+	var count_users = select_users.options.length;
+	var new_options = '';
+	
+	for (i = 0 ; i < count_available_users ; i++) {
+		if (select_available_users.options[i].selected)	{
+			if(document.all) {
+				if ( (select_users.innerHTML.indexOf('value='+select_available_users.options[i].value)) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+				}
+			}
+			else if ( (select_users.innerHTML.indexOf('value="'+select_available_users.options[i].value+'"')) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+			}
+		}
+	}
+
+	if (new_options != '') {
+
+		if(is_firefox_0)
+			fixBugInnerSelect(select_users,'###' + new_options + select_users.innerHTML);
+		else
+			select_users.innerHTML = '###' + new_options + select_users.innerHTML;
+
+		select_users.outerHTML = select_users.outerHTML;
+	}
+}
+
+function remove_user(){
+	select_users = document.getElementById('user_list');
+	
+	for(var i = 0;i < select_users.options.length; i++)
+		if(select_users.options[i].selected)
+			select_users.options[i--] = null;
+}
+
+function submitValues(button){
+    loadScript("expressoMail1_2/js/common_functions.js");
+	button.disabled = true; //Desabilita Botão para evitar varios clicks
+
+	var typeField = document.getElementById('cal[type]');
+	if (typeField && typeField.value == 'hourAppointment') {
+		if(document.getElementsByName('categories[]')[0].value == ""){
+			alert(alert_msg);
+			button.disabled = false;
+			return false;
+		}
+	}
+
+	var select_in = document.getElementById('user_list');
+	for(i = 0; i < select_in.length; i++)
+	 	select_in.options[i].selected = true;
+
+	var rptDay = document.getElementsByName( 'cal[rpt_day][]' );
+        var isChecked = false;
+
+        for(var i = 0 ; i < rptDay.length; i++)
+            if(rptDay[i].checked == true)
+                isChecked = true;  
+        
+	if( !isChecked && !document.getElementsByName( "cal[rpt_use_end]" )[0].checked && !(document.getElementsByName( "cal[recur_type]" )[0].value === "0")){
+	    alert("Agendamentos recorrentes precisam de data final da repetição");
+	    button.disabled = false;
+	    return false;
+	}
+   
+	if( !isChecked && document.getElementsByName( "cal[recur_type]" )[0].value === "2" ){
+	    //TODO: por essa mensagem no lang
+	    alert("Voce nao especificou um dia na sua repeticao semanal");
+	    button.disabled = false;
+	    return false;
+	}
+	if(document.getElementsByName( "cal[rpt_use_end]" )[0].checked){
+		if(!validate_date_order(document.getElementById('start[str]').value, document.getElementById('recur_enddate[str]').value)){
+			alert("A data final não pode ser menor que a data inicial.");
+			button.disabled = false;
+			return false;
+		}
+	}
+	//Valida data inicio nao nula
+	if(document.getElementById('start[str]').value == ''){
+		alert("Necessario preencher a data de início.");
+		document.getElementById('start[str]').focus();
+		button.disabled = false;
+		return false;
+	}
+	//Valida data inicio
+	if(document.getElementById('start[str]').value != ''){
+		if(!validate_date(document.getElementById('start[str]').value)){
+			document.getElementById('start[str]').value = '';
+			document.getElementById('start[str]').focus();
+			alert("A data de início não é válida.");
+			button.disabled = false;
+			return false;
+		}
+	}
+	//Valida data termino
+	if(document.getElementById('end[str]').value != ''){
+		if(!validate_date(document.getElementById('end[str]').value)){
+			document.getElementById('end[str]').value = '';
+			document.getElementById('end[str]').focus();
+			alert("A data de término não é válida.");
+			button.disabled = false;
+			return false;
+		}
+	}
+
+	//Valida hora inicio somente numeros	
+	if(isNaN(parseInt(document.getElementById('start_hour').value))){
+		document.getElementById('start_hour').value = '';
+		document.getElementById('start_hour').focus();
+		alert("A hora de início deve ser números.");
+		button.disabled = false;
+		return false;
+	}
+	//Valida hora inicio somente numeros	
+	if(isNaN(parseInt(document.getElementById('start_minute').value))){
+		document.getElementById('start_minute').value = '';
+		document.getElementById('start_minute').focus();
+		alert("A hora de início deve ser números.");
+		button.disabled = false;
+		return false;
+	}
+	//Valida hora termino somente numeros	
+	if(isNaN(parseInt(document.getElementById('end_hour').value))){
+		document.getElementById('end_hour').value = '';
+		document.getElementById('end_hour').focus();
+		alert("A hora do término deve ser números.");
+		button.disabled = false;
+		return false;
+	}
+	//Valida hora termino somente numeros	
+	if(isNaN(parseInt(document.getElementById('end_minute').value))){
+		document.getElementById('end_minute').value = '';
+		document.getElementById('end_minute').focus();
+		alert("A hora do término deve ser números.");
+		button.disabled = false;
+		return false;
+	}
+	 
+	//Valida hora inicial maior que final 
+	if( (document.getElementById('start_hour').value != '') && (document.getElementById('end_hour').value != '') ){
+		if( (document.getElementById('start_hour').value) > (document.getElementById('end_hour').value) ){
+			//JA ESTA ERRADO
+			document.getElementById('start_hour').value = '';
+			document.getElementById('end_hour').value = '';
+			document.getElementById('start_minute').value = '';
+			document.getElementById('end_minute').value = '';
+			document.getElementById('start_hour').focus();
+			alert("A hora final não pode ser menor que a hora inicial.");
+			button.disabled = false;
+			return false;
+		}else if ( (document.getElementById('start_hour').value) == (document.getElementById('end_hour').value) ){
+			if ( (document.getElementById('start_minute').value) > (document.getElementById('end_minute').value) ){
+				//DEU ERRO
+				document.getElementById('start_hour').value = '';
+				document.getElementById('end_hour').value = '';
+				document.getElementById('start_minute').value = '';
+				document.getElementById('end_minute').value = '';
+				document.getElementById('start_hour').focus();
+				alert("A hora final não pode ser menor que a hora inicial.");
+				button.disabled = false;
+				return false;
+			}
+		}
+	}
+
+	
+        document.getElementById('formEvent').submit();
+}	
+
+function Element(id){
+	return document.getElementById(id);
+}
+
+function loadScript(scriptPath){
+
+	if(!connector)
+		throw new Error("Error : Connector is not loaded.");
+		
+  	if (document.getElementById('uploadscript_'+scriptPath)) {
+  		return;
+   	}
+
+  	if( connector.oxmlhttp === null )
+	    connector.createXMLHTTP();
+
+	connector.oxmlhttp.open("GET", scriptPath, false);
+	connector.oxmlhttp.setRequestHeader('Content-Type','text/plain');
+	connector.oxmlhttp.send(null);
+	if(connector.oxmlhttp.status != 0 && connector.oxmlhttp.status != 200 || 	connector.oxmlhttp.status == 0 && connector.oxmlhttp.responseText.length == 0)
+		throw new Error("Error " + connector.oxmlhttp.status + "("+connector.oxmlhttp.statusText+") when loading script file '"+scriptPath+"'");
+	
+	var head = document.getElementsByTagName("head")[0];
+	var script = document.createElement("SCRIPT");
+	script.id = 'uploadscript_'+scriptPath;
+	script.type = 'text/javascript';		
+	script.text = connector.oxmlhttp.responseText;
+	head.appendChild(script);
+	return;	
+}
+
+function showExParticipants(el,path){
+	Element('tbl_ext_participants').style.display='';
+	el.style.display='none';
+	loadScript(path+"/js/common_functions.js");
+	get_lang = function( key ){
+		var translator = Element( "txt_" + key.replace(/ /g, "_") );
+		if (translator == null)
+			return "Failed translating string.";
+		var value = translator.value;
+		if(arguments.length > 1) {
+			for(j = 1; typeof(arguments[j]) != 'undefined'; j++)
+				value = value.replace("%"+j,arguments[j]);
+		}
+		return value;
+	}; 
+	loadScript(path+"/js/DropDownContacts.js");
+	loadScript(path+"/js/QuickCatalogSearch.js");
+	loadScript("calendar/templates/default/js/over_fn_exmail.js");
+	if(!contacts)
+		cExecute (path+'.db_functions.get_dropdown_contacts', save_contacts);
+}
+
+function hideExParticipants(el,path){
+	Element('a_ext_participants').style.display = '';
+	Element('tbl_ext_participants').style.display ='none';
+}
+
+function save_contacts(data){
+	contacts = data;	
+	var input_to = Element("ex_participants");
+	input_to.style.width = "100%";
+	input_to.setAttribute("wrap","soft");	
+	input_to.onfocus = function(){clearTimeout(parseInt(setTimeOutLayer));search_contacts('onfocus', this.id);};
+	input_to.onblur = function(){setTimeOutLayer=setTimeout('search_contacts("lostfocus","'+this.id+'")',100);};
+	if (!is_ie)
+	{
+		input_to.rows = 2;
+		input_to.onkeypress = function (e)
+		{
+			if ((e.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				if (((e.keyCode == 13) || ((e.keyCode == 38)||(e.keyCode == 40))) && (document.getElementById('tipDiv').style.visibility!='hidden'))
+				{
+					e.preventDefault();
+					search_contacts(e.keyCode,this.id);
+				}
+			}
+		}
+		input_to.onkeyup = function (e)
+		{
+			if ((e.keyCode != 13) && (e.keyCode != 38) && (e.keyCode != 40))
+			{
+				search_contacts(e.keyCode,this.id);
+			}
+		}
+	}
+	else
+	{
+		input_to.rows = 3;
+		input_to.onkeyup = function (e)
+		{
+			if ((window.event.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				search_contacts(window.event.keyCode,this.id);
+			}	
+		}
+	}
+}
+
+function fixBugInnerSelect(objeto,innerHTML){
+/******
+* select_innerHTML - altera o innerHTML de um select independente se é FF ou IE
+* Corrige o problema de não ser possível usar o innerHTML no IE corretamente
+* Veja o problema em: http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
+* Use a vontade mas coloque meu nome nos créditos. Dúvidas, me mande um email.
+* Versão: 1.0 - 06/04/2006
+* Autor: Micox - Náiron José C. Guimarães - micoxjcg@yahoo.com.br
+* Parametros:
+* objeto(tipo object): o select a ser alterado
+* innerHTML(tipo string): o novo valor do innerHTML
+*******/
+    objeto.innerHTML = ""
+    var selTemp = document.createElement("micoxselect")
+    var opt;
+    selTemp.id="micoxselect1"
+    document.body.appendChild(selTemp)
+    selTemp = document.getElementById("micoxselect1")
+    selTemp.style.display="none"
+    if(innerHTML.toLowerCase().indexOf("<option")<0){//se não é option eu converto
+        innerHTML = "<option>" + innerHTML + "</option>"
+    }
+    innerHTML = innerHTML.replace(/<option/g,"<span").replace(/<\/option/g,"</span")
+    selTemp.innerHTML = innerHTML
+    for(var i=0;i<selTemp.childNodes.length;i++){
+        if(selTemp.childNodes[i].tagName){
+            opt = document.createElement("OPTION")
+            for(var j=0;j<selTemp.childNodes[i].attributes.length;j++){
+                opt.setAttributeNode(selTemp.childNodes[i].attributes[j].cloneNode(true))
+            }
+            opt.value = selTemp.childNodes[i].getAttribute("value")
+            opt.text = selTemp.childNodes[i].innerHTML
+            if(document.all){ //IEca
+                objeto.add(opt)
+            }else{
+                objeto.appendChild(opt)
+            }                    
+        }    
+    }
+    document.body.removeChild(selTemp)
+    selTemp = null
+}
+
+function changeViewMode(eltype){
+	var chValue = eltype;
+	switch (chValue){
+		case 'hourAppointment':
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "none";
+			}
+
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			Field[1].parentNode.parentNode.style.display = "none";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "none";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			break;
+		case 'privateHiddenFields':
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "";
+			}
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			Field[1].parentNode.parentNode.style.display = "none";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "none";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "";
+			break;
+		default:
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "";
+			}
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "";
+			Field[1].parentNode.parentNode.style.display = "";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "";
+			break;
+	}
+
+}
+function updateTitleField(select){
+	var typeField = document.getElementsByName('cal[type]');
+	if (typeField[0].value != 'hourAppointment')
+		return;
+	var titleField = document.getElementsByName('cal[title]');
+	var optionsArray = select.childNodes;
+	titleField[0].value = '';
+	for(option in optionsArray)
+		if (optionsArray[option].selected)
+			titleField[0].value += optionsArray[option].text + ' ';
+}
+
+var __onLoad = window.onload;
+window.onload = function(){ 
+	__onLoad();
+	var cal_type = document.getElementById('cal[type]').value;
+	changeViewMode(cal_type);
+	if(cal_type == 'hourAppointment'){
+		clearTimeout(timeout_get_available_users);
+	}
+};
Index: trunk/calendar/templates/default/js/edit.js
===================================================================
--- trunk/calendar/templates/default/js/edit.js	(revision 5143)
+++ trunk/calendar/templates/default/js/edit.js	(revision 5143)
@@ -0,0 +1,137 @@
+/******************************************************************************\
+|**************************   MODULO   AGENDA   *******************************|
+|********** SCRIPT REFERENTE A CAIXA DE INCLUSAO DE PARTICIPANTES  ************|
+\******************************************************************************/
+
+// Variaveis Locais 
+	var select_in  = document.getElementById('user_list');
+	var select_out  = document.getElementById('user_list_in');	
+	var users_out = select_out ? select_out.cloneNode(true) : '';
+	var finderTimeout = '';
+																		
+// Funcoes	
+        
+        function sChangeHour(pSelect)
+        {
+            if(pSelect.selectedIndex < 1)
+                return;
+            
+            var hour = pSelect.options[pSelect.selectedIndex].value;                         
+            var sHour = hour.split(':');           
+            
+            var hHour,mHour;
+            if(pSelect.name == 'sEndHour')
+            {
+                hHour = document.getElementById('end_hour');
+                mHour = document.getElementById('end_minute');
+            }
+            else if(pSelect.name == 'sStartHour')
+            {
+                hHour = document.getElementById('start_hour');
+                mHour = document.getElementById('start_minute');
+            }    
+            
+            hHour.value = sHour[0];
+            mHour.value = sHour[1];
+        }
+        
+	function showExParticipants(el,path){
+		document.getElementById('tbl_ext_participants').style.display='';
+		el.style.display='none';
+	}
+	
+	function hideExParticipants(el,path){
+		document.getElementById('a_ext_participants').style.display = '';
+		document.getElementById('tbl_ext_participants').style.display ='none';
+	}
+							
+	function optionFinderTimeout(obj){
+
+		clearTimeout(finderTimeout);	
+		var oWait = document.getElementById("wait");
+		oWait.innerHTML = 'Buscando...';
+		finderTimeout = setTimeout("optionFinder('"+obj.id+"')",500);
+	}
+	function optionFinder(id) {	
+		var oWait = document.getElementById("wait");
+		var oText = document.getElementById(id);
+		for(var i = 0;i < select_out.options.length; i++)				
+			select_out.options[i--] = null;
+																							
+		for(i = 0; i < users_out.length; i++){																							
+			if(users_out[i].text.substring(0 ,oText.value.length).toUpperCase() == oText.value.toUpperCase()) {
+				sel = select_out.options;						
+				option = new Option(users_out[i].text,users_out[i].value);				
+				sel[sel.length] = option;
+			}
+		}
+		oWait.innerHTML = '&nbsp;';
+	}			
+									
+	function rem()
+	{
+		for(var i = 0;i < select_in.options.length; i++)				
+			if(select_in.options[i].selected)
+				select_in.options[i--] = null;																	
+	}
+	
+		
+    function show_disponibility() { 
+		 
+    	participants = ""; 
+		    combo = document.getElementById('user_list'); 
+		    if(combo.length==0) { 
+		    	var msg_ = document.getElementById("set_participants").value;
+				alert(msg_);
+		        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 openListUsers(newWidth,newHeight, owner){					
+		newScreenX  = screen.width - newWidth;		
+		newScreenY  = 0;		
+		window.open('calendar/templates/default/listUsers.php?owner='+owner,"","width="+newWidth+",height="+newHeight+",screenX="+newScreenX+",left="+newScreenX+",screenY="+newScreenY+",top="+newScreenY+",toolbar=no,scrollbars=yes,resizable=no");
+	}
+
+ 	function adicionaListaCalendar() 
+ 	{
+		var select = window.document.getElementById('user_list_in');
+		var selectOpener = window.opener.document.getElementById('user_list');
+		for (i = 0 ; i < select.length ; i++) {				
+
+			if (select.options[i].selected) {
+				isSelected = false;
+
+				for(var j = 0;j < selectOpener.options.length; j++) {																			
+					if(selectOpener.options[j].value == select.options[i].value){
+						isSelected = true;						
+						break;	
+					}
+				}
+
+				if(!isSelected){
+
+					option = window.opener.document.createElement('option');
+					option.value =select.options[i].value;
+					option.text = select.options[i].text;
+					selectOpener.options[selectOpener.options.length] = option;	
+				}
+				
+			}
+		}
+		selectOpener.options[selectOpener.options.length-1].selected = true;
+ 	}
+	
+// Fim        
Index: trunk/calendar/templates/default/js/search.js
===================================================================
--- trunk/calendar/templates/default/js/search.js	(revision 5143)
+++ trunk/calendar/templates/default/js/search.js	(revision 5143)
@@ -0,0 +1,125 @@
+var searchTimeout;
+
+function lang(key){
+	return document.getElementById("txt_"+key).value;
+}
+
+function remove_user(id){
+	if(!confirm(lang("confirm")))
+		return true;	
+	var handler_rem_user = function(data){
+		if(data) {
+			var tr = document.getElementById(id);
+			tr.parentNode.removeChild(tr);
+		}
+	}	
+	cExecute ('calendar.uigroup_access.rem_user&id='+id, handler_rem_user);
+}
+function add_user(){
+	var select_users = document.getElementById("user");
+	var select_groups = document.getElementById("group");
+	var a_rights = new Array("L","A","E","R","P");
+	var rights = '';
+	for(var z = 0; z < a_rights.length; z++){
+		var check = document.getElementById("right_"+a_rights[z]);
+		if(check.checked){
+			rights += check.value;
+		}
+	}
+	if(!select_users.value){
+		alert(lang("nouser"));
+		return;
+	}
+	else if(!select_groups.value){
+		alert(lang("nogroup"));
+		return;
+	}
+	else if(!rights){
+		alert(lang("nopermissiontype"));
+		return;
+	}
+	
+	var str = select_users.value+";"+select_groups.value;
+	var handler_add_user = function(data){
+		
+		if(data){
+			var t = document.getElementById('tbody_list');
+			var tr = document.createElement("TR");
+			tr.bgColor = "#DCDCDC";
+			var td1 = document.createElement("TD");
+			var td2 = document.createElement("TD");
+			var td3 = document.createElement("TD");
+			var td4 = document.createElement("TD");
+			tr.id = str;
+			td1.innerHTML = "<b>&nbsp;&nbsp;"+select_users[select_users.selectedIndex].text+"</b>";
+			td2.innerHTML = rights;
+			td2.align = "center";
+			td3.innerHTML = "&nbsp;&nbsp;"+select_groups[select_groups.selectedIndex].text;
+			td4.innerHTML = "<button  title='remove' type='button' onClick='javascript:remove_user(\""+str+"\");'><img src='"+document.getElementById("template_set").value+"/images/delete.png' style='vertical-align: middle;'/></button>";
+			tr.appendChild(td1);
+			tr.appendChild(td2);
+			tr.appendChild(td3);
+			tr.appendChild(td4);
+			t.appendChild(tr);
+			alert(lang("success"));
+		}
+		else{
+			alert(lang("exist"));
+		}
+	}
+	cExecute ('calendar.uigroup_access.add_user&id='+str+"&rights="+rights, handler_add_user);
+	return true;
+		
+}
+function search_object(input, id_span, id_select, type, event)
+{
+// 	clearTimeout(searchTimeout);	
+// 	var spam = document.getElementById(id_span);
+// 	if (input.value.length <= 3){
+// 		spam.innerHTML = lang("typemoreletters").replace("X",4 - input.value.length);
+// 	}else{
+// 		spam.innerHTML = lang("searching")+'...';
+// 		searchTimeout = setTimeout("search_ldap('"+input.id+"','"+id_span+"','"+id_select+"','"+type+"')",750);
+// 	}
+	if( event && event.keyCode !== 13 )
+	    return;
+	
+	search_ldap(input.id, id_span, id_select, type);
+}
+
+function search_ldap(id_input, id_span, id_select, type)
+{
+// 	var search = document.getElementById(id_input).value;
+// 	
+// 	var handler_search_user = function(data)
+// 	{
+// 		var spam = document.getElementById(id_span);
+// 		select_available_users = document.getElementById(id_select);
+// 		if (data.status == 'false')
+// 		{
+// 			spam.innerHTML = data.msg;
+// 			// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+// 			select_available_users.innerHTML = '#';
+// 			select_available_users.outerHTML = select_available_users.outerHTML;
+// 			return;
+// 		}	
+// 		spam.innerHTML = '';
+// 		// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+// 		select_available_users.innerHTML = '#' + data;
+// 		select_available_users.outerHTML = select_available_users.outerHTML;
+// 	}
+	var search = Element( id_input ).value;
+
+	var url = 'calendar.uigroup_access.search_user&search='+search+"&type="+type;
+	
+	var fillHandler = function( fill ){
+	
+	    Element( id_select ).innerHTML = fill;
+	
+	    return( fill !== "" );
+	};
+
+// 	cExecute ('calendar.uigroup_access.search_user&search='+search+"&type="+type, handler_search_user);
+
+	userFinder( search, fillHandler, url, id_span );
+}
Index: trunk/calendar/templates/default/js/finder.js
===================================================================
--- trunk/calendar/templates/default/js/finder.js	(revision 5143)
+++ trunk/calendar/templates/default/js/finder.js	(revision 5143)
@@ -0,0 +1,435 @@
+
+var current_value = "";
+
+var default_limit = 0;
+
+var sizelimit = 10;
+
+function Element( id )
+{
+    return document.getElementById( id );
+}
+
+function optionFind( id, selectId, url, ctxId, labelId )
+{
+    var fillHandler = function( fill, raw ){
+
+	return fillContentSelect( fill, selectId );
+
+    };
+
+    getAvailable( id, fillHandler, url, ctxId, labelId, true );
+}
+
+function getAvailable( id, fillHandler, url, ctxId, labelId, bypass )
+{
+    if( id )
+    {
+	var sentence = Element( id );
+
+	sentence = sentence ? sentence.value : id;
+	
+	url += "&filter=" + sentence + "&sentence=" + sentence;
+    }
+
+    if( ctxId )
+    {
+	var ctx = Element( ctxId );
+	
+	ctx = ctx ? ctx.value : ctxId;
+
+	url += "&context=" + ctx;
+    }
+
+    if( bypass )
+	bypass = bypassParser;
+
+    userFinder( sentence, fillHandler, url, bypass, labelId );
+}
+
+var default_field = "cn";
+
+function userFinder( sentence, selectId, url, handler, labelId )
+{
+    if( sentence === current_value )
+	return;
+
+    //current_value = sentence;
+
+    if( typeof limit === "undefined" )
+	limit = default_limit;
+
+    //TODO: tornar esse limite configuravel de acordo com a configuracao do expresso
+    if( sentence.length < limit )
+	return( false );
+
+    if( typeof handler === "string" &&
+	typeof labelId === "undefined" )
+	labelId = handler,
+	handler = undefined;
+
+    if( typeof get_lang === "undefined" )
+	get_lang = function( key ){
+	    var translator = Element( "txt_" + key );
+
+	    return translator ? translator.value : key;
+	};
+
+    var urlHandler = function(){
+
+	    if( labelId )
+		Element( labelId ).innerHTML = get_lang('searching') + '...';
+
+	    if( typeof url === "function" )
+		url = url();
+
+	    return( url );
+    };
+
+    var defaultParser = function( data, raw ){
+
+	if( labelId )
+	    Element( labelId ).innerHTML = '&nbsp;';
+
+	    var result = false;
+
+	    if( handler )
+		result = handler( data, raw );
+
+	    if( result )
+		return( result );
+
+	if( typeof data === "string" )
+	    return( data );
+
+	return stackParser( data, default_field );
+    };
+
+    var fillHandler = function( fill, raw )
+    {
+	var sizeof = 0;
+
+	if( typeof selectId === "string" )
+	    sizeof = fillSelect( fill, selectId, default_field );
+	else
+	    sizeof = selectId( fill, raw );
+
+	if( labelId && sizeof >= sizelimit )
+	    Element( labelId ).innerHTML = 'Muitos resultados encontrados. Por favor, refine sua busca.';
+
+	return( !sizeof );
+    }
+
+    return finder( sentence, fillHandler, urlHandler, defaultParser );
+}
+
+function finder( sentences, fillHandler, url, parser )
+{
+    //caso fillHandler nao seja uma funcao, usar a default
+//     if( typeof fillHandler === "string" )
+//     {
+// 	var selectId = fillHandler;
+// 
+// 	fillHandler = function( fill ){
+// 
+// 	    return !fillSelect( fill, selectId, default_field );
+// 
+// 	};
+//     }
+
+    return lookup( sentences, fillHandler, url, parser, fillHandler );
+}
+
+function getExp( sentence )
+{
+   sentence = sentence.replace(/^\s*/, "").replace(/\s*$/, "");
+ 
+   sentence = sentence.replace( / /gi, ".*" );
+
+   sentence = new RegExp( ".*" + sentence + ".*", "i" );
+
+    return( sentence );
+}
+
+var options_cache = {};
+
+function setOptions( fill, select, field )
+{
+    for( var value in fill )
+    {
+	if( !options_cache[value] )
+	     options_cache[value] = {};
+
+	if( !options_cache[value][field] )
+	     options_cache[value][field] = new Option( fill[value][field], value );
+
+	select[select.length] = options_cache[value][field];
+    }
+
+    return( select );
+}
+
+function fillSelect( fill, selectId, field )
+{
+    //recupera as options do respectivo select
+    var select = Element( selectId ).options;
+
+    //Limpa todo o select
+    select.length = 0;
+
+    //Inclui usuario comecando com a pesquisa
+    select = setOptions( fill, select, field );
+
+    //chama o server side caso nao encontre resultado nenhum com essa sentenca
+    return( select.length );
+}
+
+function fillContentSelect( fill, selectId )
+{
+    if( typeof fill === "string" )
+    {
+	var select = Element( selectId );
+
+	select.innerHTML = fill;
+
+	return( select.options.length );
+    }
+
+    var content = "";
+
+    for( var section in fill )
+    {
+	if( !fill[section] || fill[section] === "" )
+	    continue;
+
+	var entry = entryTag( section );
+
+	content += entry.outerHTML;
+	content += fill[section];
+    }
+
+    return fillContentSelect( content, selectId );
+}
+
+
+function entryTag( label, select )
+{
+    var line = '-------------------';
+
+    var option = new Option( line + ' ' + get_lang(label) + ' ' + line + ' ', -1 );
+    option.disabled = true;
+
+    if( typeof select === "undefined" )
+	return( option );
+
+    if( typeof select === "string" )
+	select = Element( select ).options;
+
+    if( select.options )
+	select = select.options;
+
+    select[select.length] = option;
+}
+
+function fillGroupableSelect( fill, selectId, groupHandler, field )
+{
+    var groups = {};
+
+    var select = Element( selectId ).options;
+
+    var sizeof = select.length = 0;
+
+    for( value in fill )
+    {
+	var target = fill[value];
+
+	var group = groupHandler( target );
+
+	if( !groups[ group ] )
+	    groups[ group ] = {};
+
+	groups[ group ][ value ] = target;
+
+	sizeof++;
+    }
+
+    for( groupId in groups )
+    {
+	var group = groups[ groupId ];
+
+	 entryTag( groupId, select );
+
+	select = setOptions( group, select, field );
+    }
+
+    return( sizeof );
+}
+
+function flipParser( data )
+{
+    var result = {};
+
+    for( var section in data )
+    {
+	var target = data[section];
+
+	for ( var key in target )
+	{
+	    if( !result[key] )
+		result[key] = {};
+
+	    result[key][section] = target[key];
+	}
+    }
+
+    return( result );
+}
+
+function stackParser( data, field )
+{
+    if( !data ) return( false );
+
+    for( var section in data )
+	data[section] = normalize( data[section], field );
+
+    return( data );
+}
+
+function bypassParser( x ){
+    return( x );
+}
+
+var userData = {};
+
+function lookup( matchers, fillHandler, url, parser, callback )
+{
+    var serverCallback = false;
+
+    if( url )
+    {
+	//handler chamado pelo callback do servidor para repopular.
+	serverCallback = function( filters, handler ){
+
+	    var refill = function( userd, data ){
+
+		//no caso de existir um custom callback
+		if( callback )
+		    if( !callback( data, userd ) )
+			return;
+
+		//filter( filters, handler );
+
+	    };
+
+	    search( url, refill, parser );
+	};
+    }
+
+    serverCallback( matchers, fillHandler, serverCallback );
+}
+
+function filter( filters, fillHandler, emptinessHandler )
+{
+    filters = normalize( filters );
+
+    var fill = {};
+
+    //varrer todas as sentencas e secoes especificas
+    for( key in userData )
+    {
+	var user = userData[key];
+
+	if( !user ) continue;
+
+	var filtered = false;
+
+	//populando o mapa filtrando pela determinada sentenca
+	for( section in filters )
+	{
+	    if( filtered ) break;
+
+	    //filtro para a secao especifica.
+	    var criteria = filters[section];
+
+	    var target = user[section] || user;
+
+	    if( !criteria( target ) )
+		filtered = true;
+	}
+
+	if( !filtered )
+	    fill[key] = user;
+    }
+
+    //tenta chamar o handler para popular, caso nao consiga chama o server side
+    if( fillHandler )
+	if( !fillHandler( fill ) && emptinessHandler )
+	    return emptinessHandler( filters, fillHandler );
+
+    return( fill );
+}
+
+function search( url, callback, parser )
+{
+    var handler = function( data )
+    {
+	if( !cExecute )
+	    data = unserialize( data );
+
+	var dt = false;
+
+	if( typeof data == "string" && data.charAt(0) === '{' )
+	{
+	    try{
+		dt = data;
+		data = (new Function("return " + data))();
+	    }
+	    catch(e){
+	    }
+	}
+
+// 	if( data && typeof data !== "string" && data.nosession )
+// 	    window.location.reload( false );
+
+	if( parser )
+	    data = parser( data, dt );
+
+	if( callback )
+	    callback( userData, data );
+    }
+
+    if( typeof url === "function" )
+	url = url();
+
+    if( typeof cExecute !== "undefined" )
+	return cExecute( url, handler );
+
+    return this.Connector.newRequest( 'search', url, 'GET', handler );
+}
+
+function normalize( raw, field )
+{
+    if( raw instanceof RegExp )
+    {
+	var exp = raw;
+
+	raw = function( match ){
+	    return exp.test( match );
+	}
+    }
+
+    if( typeof field !== "undefined" && raw !== "object" )
+    {
+	var content = raw;
+
+	raw = {};
+	
+	raw[field] = content;
+    }
+
+    if( typeof raw === "object" )
+	for( var key in raw )
+	    raw[key] = normalize( raw[key] );
+
+    return( raw );
+}
Index: trunk/calendar/templates/default/js/suggestion.js
===================================================================
--- trunk/calendar/templates/default/js/suggestion.js	(revision 5143)
+++ trunk/calendar/templates/default/js/suggestion.js	(revision 5143)
@@ -0,0 +1,169 @@
+/**
+ * Gerenciamento das sugestões de mudança de horário de compromissos feitas pelos usuários.
+ * Prognus Software Livre - http://www.prognus.com.br
+ */
+
+var data_inicio_original; 
+var data_final_original;  
+var hora_inicio_original;
+var minuto_inicio_original;
+var hora_final_original;    
+var minuto_final_original;
+ 
+ window.onload = function(){
+  if(location.href.indexOf("type=1") != -1)
+	show_suggestion();
+}
+
+function validate_hour_field(data,begin)
+{	
+	begin==0? id='hora_inicio' : id='hora_final';
+	if(isNaN(data.value))
+	{
+		alert("A hora deve ser um número");
+		document.getElementById(id).value = "";
+		return;
+	}
+	if(data.value < 0 || data.value >= 24)
+	{
+		alert("A hora deve estar entre 0 e 23");
+		document.getElementById(id).value = "0";
+		return;
+	}
+}
+
+function validate_minute_field(data,begin)
+{
+	begin==0? id='minuto_inicio' : id='minuto_final';
+	if(isNaN(data.value))
+	{
+		alert("O minuto deve ser um número");
+		document.getElementById(id).value = "";
+		data.focus();
+		return;
+	}
+	if(data.value < 0 || data.value > 59)
+	{
+		alert("Os minutos devem estar entre 0 e 59"); 
+		document.getElementById(id).value = "";
+		data.focus();
+		return;
+	}
+}
+
+function validate_date_field(data, begin)
+{
+	begin==0? id='data_inicio' : id='data_final';
+	if(isNaN(data.value) && data.value.indexOf('/')==-1)
+	{
+		alert("Por favor, complete a data somente com números");
+		document.getElementById(id).value = "";
+		return;
+	}
+	var expReg =  /^((((0?[1-9]|1\d|2[0-8])\/(0?[1-9]|1[0-2]))|((29|30)\/(0?[13456789]|1[0-2]))|(31\/(0?[13578]|1[02])))\/((19|20)?\d\d))$|((29\/0?2\/)((19|20)?(0[48]|[2468][048]|[13579][26])|(20)?00))$/;
+    if ((data.value.match(expReg)) && data.value!='') 
+	{
+		var dts = new Date();  
+        var dia_atual = dts.getDate();
+        var mes_atual = dts.getMonth()+1;
+        var ano_atual = dts.getFullYear();   
+
+        var dia = data.value.substring(0,2);
+        var mes = data.value.substring(3,5);
+        var ano = data.value.substring(6,10);
+		
+		if((ano_atual>ano) || ((ano_atual==ano) && (mes_atual>mes)) || ((ano_atual==ano) && (mes_atual==mes) && (dia_atual>dia)))
+		{
+			alert("Formato inválido de data.\nCompromisso mais antigo que a data atual.");
+			data.value = "";
+			data.focus();
+		}
+    } 
+	else 
+	{
+		if(data.value != '')
+		{
+			alert("Formato inválido de data.");
+			data.value = "";
+			data.focus();
+		}
+    } 
+}
+
+
+function insere_barras(begin)
+{
+	begin==0? id='data_inicio' : id='data_final';
+	obj = document.getElementById(id);
+	value = obj.value;
+	l = value.toString().length;
+	switch(l){
+		case 2:
+			obj.value = value + "/";
+		break;
+		case 5:
+			obj.value = value + "/";
+		break;
+	}
+}
+
+
+function trata_botao_submit()
+{
+	inicio = document.getElementById('data_inicio').value.split("/");
+	fim    = document.getElementById('data_final').value.split("/");
+	
+	if((document.getElementById('data_inicio').value == data_inicio_original) && (document.getElementById('data_final').value == data_final_original) && (document.getElementById('hora_inicio').value == hora_inicio_original) && (document.getElementById('minuto_inicio').value == minuto_inicio_original) && (document.getElementById('hora_final').value == hora_final_original) && (document.getElementById('minuto_final').value == minuto_final_original))
+	{
+		alert("A sugestão deve ser diferente do compromisso original.");
+		return false;
+	}
+	
+	if((inicio[2] > fim[2]) || ((inicio[1] > fim[1]) && (inicio[2]<=fim[2])) || (((inicio[0] > fim[0]) && ((inicio[1]<=fim[1]) && (inicio[2]<=fim[2])))))
+	{
+		alert("Data de início maior que data de fim.");
+		return false;
+	}
+
+	if((parseInt(document.getElementById('hora_inicio').value) > parseInt(document.getElementById('hora_final').value)) || ((parseInt(document.getElementById('minuto_inicio').value) > parseInt(document.getElementById('minuto_final').value)) && (parseInt(document.getElementById('hora_inicio').value) <= parseInt(document.getElementById('minuto_final').value))))
+	{
+		alert("Hora de início maior que hora de término.");
+		return false;
+	}
+	
+	if((document.getElementById('data_inicio').value =="") || (document.getElementById('data_final').value =="") || (document.getElementById('hora_inicio').value =="") || (document.getElementById('minuto_inicio').value =="") || (document.getElementById('hora_final').value =="") || (document.getElementById('minuto_final').value =="")) 
+	{	
+		alert("Por favor, preencha todos os campos para enviar a solicitação.");
+		return false;
+	}
+	else
+	{
+		alert("Novo horário sugerido com sucesso.\nUm email foi enviado para o criador do evento com sua sugestão."); 
+		window.close();
+	}
+}
+
+
+function show_suggestion()
+{
+	divElement = document.getElementById('suggestion');
+	divElement.style.visibility = 'visible';
+	divElement.style.display = 'block';
+	
+	data_inicio_original    = document.getElementById('data_inicio').value;
+	data_final_original     = document.getElementById('data_final').value;
+	hora_inicio_original    = document.getElementById('hora_inicio').value;
+	minuto_inicio_original  = document.getElementById('minuto_inicio').value;
+	hora_final_original     = document.getElementById('hora_final').value;
+	minuto_final_original   = document.getElementById('minuto_final').value;
+
+	return( false );
+}
+
+
+function fecha_sugestao()
+{
+	divSugestao = document.getElementById('suggestion');
+	divSugestao.style.visibility = "hidden";
+	divSugestao.style.display    = "none";
+}
Index: trunk/calendar/templates/default/js/over_fn_exmail.js
===================================================================
--- trunk/calendar/templates/default/js/over_fn_exmail.js	(revision 5143)
+++ trunk/calendar/templates/default/js/over_fn_exmail.js	(revision 5143)
@@ -0,0 +1,281 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** PLUGIN USING AJAX EXPRESSOMAIL COMPONENT - OVERWRITE FUNCTIONS   **|
+\******************************************************************************/
+
+/******************************************************************************\
+|** Function      : emQuickSearch *********************************************|
+|** Original File : <expressoMail_module>/js/common_functions.js **************|
+\******************************************************************************/
+window.onresize = function(){};
+function emQuickSearch(el){
+
+	var emailList = el.value;
+	var field = el.id;
+	var ex_participants = Element("ex_participants");
+	var quickSearchKeyBegin;
+	var quickSearchKeyEnd;
+	
+	var handler_emQuickSearch = function(data){
+		window_DropDownContacts = Element('tipDiv');
+		if (window_DropDownContacts.style.visibility != 'hidden'){
+			window_DropDownContacts.style.visibility = 'hidden';
+		}
+		//if ((!data.status) && (data.error == "many results")){
+		if (data != null && data.length >= data.maxResult){
+			alert(get_lang('More than %1 results. Please, try to refine your search',data.maxResult));
+		}
+			
+		if (data != null && data.length > 0){
+			QuickCatalogSearch.showList(data, quickSearchKeyBegin, quickSearchKeyEnd);
+		}
+		else
+			 alert(document.getElementById('txt_none_result').value);
+		return true;
+	}
+	ex_participants.focus(); 				//mecessary for IE.
+	var i = getPosition(ex_participants); //inputBox.selectionStart;
+	var j = --i;
+
+    while ((j >= 0) && (emailList.charAt(j) != ',')){j--};
+    quickSearchKeyBegin = ++j;
+
+    while ((i <= emailList.length) && (emailList.charAt(i) != ',')){i++};
+    quickSearchKeyEnd = i;
+
+    var search_for = trim(emailList.substring(quickSearchKeyBegin, quickSearchKeyEnd));
+
+	if (search_for.length < 4){
+		alert(document.getElementById('txt_min_search').value);
+		return false;
+	}
+	
+	cExecute ("expressoMail1_2.ldap_functions.quicksearch&search_for="+search_for+"&field="+field, handler_emQuickSearch);
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.transfer_result ************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.transfer_result = function (field, ID, begin, end){
+	cm = document.getElementById('select_QuickCatalogSearch');
+	option_selected = cm.options[cm.selectedIndex].value + ", ";
+	emailList = Element("ex_participants").value;		
+	new_emailList = emailList.substring(0, begin) + option_selected + emailList.substring((parseInt(end) + 2), emailList.length);
+	document.getElementById("ex_participants").value = new_emailList;
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.close_QuickSearch_window ***|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.close_QuickSearch_window = function (){
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.showWindow *****************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.showWindow = function (div)
+{
+	if(! div) {
+		alert(get_lang('The list has no participant.'));
+		return;
+	}
+						
+	if(! this.arrayWin[div.id]) {
+		div.style.width = "700px";
+		div.style.height = "230px";
+		var title = get_lang('The results were found in the Global Catalog')+':';
+		var wHeight = div.offsetHeight + "px";
+		var wWidth =  div.offsetWidth   + "px";
+		div.style.width = div.offsetWidth - 5;
+
+		win = new dJSWin({			
+			id: 'QuickCatalogSearch_'+div.id,
+			content_id: div.id,
+			width: wWidth,
+			height: wHeight,
+			y:'300px',
+			top: '300px',
+			title_color: '#3978d6',
+			bg_color: '#eee',
+			title: title,						
+			title_text_color: 'white',
+			button_x_img: 'phpgwapi/images/winclose.gif',
+			border: true });
+		
+		this.arrayWin[div.id] = win;
+		win.draw();
+	}
+	else {
+		win = this.arrayWin[div.id];
+	}
+
+	win.open();
+	document.getElementById('select_QuickCatalogSearch').focus();
+}	
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.showList *****************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+
+	emQuickCatalogSearch.prototype.showList = function(data, begin, end){
+		id = '1';
+		_this = this;
+		var el = document.createElement("DIV");
+		el.style.visibility = "hidden";
+		el.style.position = "absolute";
+		el.style.left = "0px";
+		el.style.top = "0px";
+		el.style.width = "0px";
+		el.style.height = "0px";
+		el.id = 'window_QuickCatalogSearch';
+		document.body.appendChild(el);
+		el.innerHTML = "";
+		
+		if (document.getElementById('select_QuickCatalogSearch') == null){
+
+			var title_innerHTML = get_lang('Select a name') + ':';
+			if (data.quickSearch_only_in_userSector)
+				title_innerHTML += "<font color='BLACK' nowrap> ("+get_lang('Showing only the results found in your organization')+".)</font>"
+
+			var title = document.createElement("SPAM");
+			title.id = 'window_QuickCatalogSearch_title';
+			title.innerHTML = "&nbsp;&nbsp;<b><font color='BLUE' nowrap>"+title_innerHTML+"</font></b><br>&nbsp;&nbsp;";
+			el.appendChild(title);
+			
+			var cmb = document.createElement("SELECT");
+			cmb.id = "select_QuickCatalogSearch";
+			cmb.style.width = "685px";
+			cmb.size = "12";
+			cmb.ondblclick = function (e) { 
+				QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+			}
+			cmb.onkeypress = function (e)
+			{
+				if (is_ie)
+				{
+					if ((window.event.keyCode) == 13)
+					{
+						QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+					}
+					else if ((window.event.keyCode) == 27)
+					{
+						QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);
+					}
+				}
+				else
+				{					
+					if ((e.keyCode) == 13)
+					{
+						QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+					}
+					else if ((e.keyCode) == 27)
+					{
+						QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);
+					}
+				}
+			};
+			el.appendChild(cmb);
+
+			var space = document.createElement('SPAN');
+			space.innerHTML = "<BR>&nbsp;&nbsp;";
+			el.appendChild(space);
+
+			var butt = document.createElement('BUTTON');
+			var buttext = document.createTextNode('OK');
+			butt.id = "QuickCatalogSearch_button_ok";
+			butt.appendChild(buttext);
+			butt.onclick = function () {
+				QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+			};
+			el.appendChild(butt);
+
+			var space = document.createElement('SPAN');
+			space.innerHTML = "&nbsp;&nbsp;";
+			el.appendChild(space);
+
+			var butt = document.createElement('BUTTON');
+			butt.id = "QuickCatalogSearch_button_close";
+			var buttext = document.createTextNode(get_lang('Close'));
+			butt.appendChild(buttext);
+			butt.onclick = function () { QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);};
+			el.appendChild(butt);
+		}
+		else{
+			var title_innerHTML = get_lang('Select a name') + ':';
+			if (data.quickSearch_only_in_userSector)
+				title_innerHTML += "<font color='BLACK' nowrap> ("+get_lang('Showing only the results found in your organization')+".)</font>"
+
+			var title = Element('window_QuickCatalogSearch_title');
+			title.innerHTML = "&nbsp;&nbsp;<b><font color='BLUE' nowrap>"+title_innerHTML+"</font></b><br>&nbsp;&nbsp;";
+			
+			var cmb = document.getElementById('select_QuickCatalogSearch');
+			cmb.ondblclick = function (e) { 
+				QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+			}
+			cmb.onkeypress = function (e)
+			{
+				if (is_ie)
+				{
+					if ((window.event.keyCode) == 13)
+					{
+						QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+					}
+					else if ((window.event.keyCode) == 27)
+					{
+						QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);
+					}
+				}
+				else
+				{
+					if ((e.keyCode) == 13)
+					{
+						QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);
+					}
+					else if ((e.keyCode) == 27)
+					{
+						QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);
+					}
+				}
+			};
+
+			for (i=0; i<cmb.length; i++)
+				cmb.options[i--] = null;
+			
+			var butt_ok = document.getElementById("QuickCatalogSearch_button_ok");
+			var butt_close = document.getElementById("QuickCatalogSearch_button_close");
+			butt_ok.onclick = function () {QuickCatalogSearch.transfer_result(data.field, data.ID, begin, end);};
+			butt_close.onclick = function () {QuickCatalogSearch.close_QuickSearch_window(data.field, data.ID);};
+		}
+
+		for (i=0; i<data.length; i++){
+			var Op = document.createElement("OPTION");
+			Op.text = data[i].cn + ' (' + data[i].mail + ')';
+			if (data[i].phone != '')
+				Op.text += ' - ' + data[i].phone;
+			if (data[i].ou != '')
+				Op.text += ' - ' + data[i].ou; // adicionado "data[i].ou" para exibir setor (F9)
+			Op.value = '"' + data[i].cn + '" ' + '<' + data[i].mail + '>';
+			cmb.options.add(Op);
+		}
+		cmb.options[0].selected = true;
+		_this.showWindow(el);
+	}
+/******************************************************************************\
+|** Function      :  DRAG *****************************************************|
+|** Original File : phpgwapi/js/wz_dragdrop/wz_dragdrop.js ********************|
+\******************************************************************************/
+var over_fn_DRAG = DRAG;
+DRAG = function (event){
+
+		if(is_ie)
+			return false;
+		else
+			over_fn_DRAG(event);
+}		
