/*
Jorge - frontend for mod_logdb - ejabberd server-side message archive module.
Copyright (C) 2009 Zbigniew Zolkiewski
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
if (__FILE__==$_SERVER['SCRIPT_FILENAME']) {
	header("Location: index.php?act=logout");
	exit;
}
function get_user_agent($_SERVER) {
	
	if (preg_match("/Macintosh/i",$_SERVER['HTTP_USER_AGENT'])) {
			return true;
		}
		else{
			return false;
	}
	return false;
}
function getmicrotime(){
	list($usec, $sec) = explode(" ",microtime());
	return ((float)$usec + (float)$sec);
}
function query_nick_name($ejabberd_roster,$talker, $server="") {
	$nickname = $ejabberd_roster->get_nick("$talker"."@"."$server");
	if ($nickname=="") { 
	
			$nickname=$talker; 
			
		}
	return $nickname;
}
function validate_date($tslice) {
	list($ye, $mo, $da) = split("-", $tslice);
	return checkdate($mo,$da,$ye);
}
function check_registered_user ($sess,$ejabberd_rpc,$enc) {
	
	if (!$sess->is_registered('uid_l') OR !$sess->is_registered('uid_p')) {
			
			return false;
  		}
		else {
			if ($enc->decrypt_url($sess->get('uid_p')) === true) {
					$uid_p = $enc->single;
				}
				else {
					return false;
			}
			$ejabberd_rpc->set_user($sess->get('uid_l'),$uid_p);
			if ($ejabberd_rpc->auth() === true) {
					return true;
				}
				else {
			
					return false;
			}
	}
	return false;
}
function is_query_from($query) {
	list($from,$talker,$query_p) = split(":",$query);
	$from=trim($from);
	if ($from=="from") {
			$qquery[from] = "t";
			$qquery[talker] = trim($talker);
			$qquery[talker] = str_replace("//","@",$qquery[talker]); // hack for parametrized search
			if ($query_p) {
				
					$qquery[query] = $query_p;
					$qquery[words] = "t";
					return $qquery;
					
				}
				else {
					$qquery[words] = "f";
					return $qquery;
					
			}
	
		}
		else {
			// normal search
			return "f";
	}
}
function verbose_date($raw_date,$months_names = null,$weekdays = null,$t = false,$y = false) {
	
	// English calendar arrays. Here we convert names from english calendar to other language. Make sure your locale in php work with default set to english.
	$english_months = array("January","February", "March", "April", "May","June","July","August","September","October", "November","December");
	$english_days = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
	// Various formats
	if ($t === true) {
			return str_replace($english_days,$weekdays,strftime("%e.%m (%A)",strtotime("$raw_date")));
		
		}
		elseif($y === true) {
			return str_replace($english_months,$months_names,strftime("%B %Y", strtotime("$raw_date")));
		}
		else{
			return str_replace($english_months,$months_names,strftime("%e %B %Y", strtotime("$raw_date")));
	}
	
}
function validate_start($start) {
	if (!ctype_digit($start)) { 
	
		return false;
	
	}
	if (fmod($start,10)=="0") { 
	
			return true;
			
		} 
		else { 
		
			return false;
			
	}
}
function db_size() {
	$result = mysql_query("show table status");
	$size = 0;
	while($row = mysql_fetch_array($result)) {
		$size += $row["Data_length"];
	
	}
	$size = round(($size/1024)/1024, 1);
	return $size;
}
function verbose_split_line($in_minutes,$verb_h,$in_min) {
	if ($in_minutes>60) {
		return $verb_h;
	}
	elseif ($in_minutes<60)  {
		return $in_minutes." ".$in_min;
	}
}
function cut_nick($nick) {
	if (strlen($nick)> 25) {
		$nick=substr($nick,0,25)."...";
	}
	
	return $nick;
}
function new_parse_url($text) {
	$text = ereg_replace("([[:alpha:]]+://www|[[:alpha:]]+://)[^<>[:space:]]+[[:alnum:]/]",
                     "\\0", $text);
	// disabled for now
	#$text = ereg_replace("[^://]?www[^<>[:space:]]+[[:alnum:]/]",
        #            "\\0", $text);
	
	return $text;
}
function calendar($db,$user_id,$xmpp_host,$y,$m,$days,$token,$url_key,$left,$right,$selected,$lang,$view_type,$c_type,$name_peer=0,$server_peer=0,$cal_days=0,$enc=null,$months_names,$weekdays) {
	
	$days=$days;
	$month = $m;
	$year = $y;
//create arrays for the calendar
    $months_days = array("31","28","31","30","31","30","31","31",
                         "30","31","30","31");
	$days_array = array("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
//removes the 0 from start of month - can't find array key with 0
    if(strlen($month)==1){
        $month= str_replace("0","",$month);
    }
    else{
        $month=$month;
    }
//reset month to the array key match (array starts at 0)
    $month= $month-1;
//find the days in the month
    $days_in_month = $months_days[$month];
//$m is used to find month
    $m = $month+1;
//find the first day of the month     
 
    $time = date("M D Y H:i:s", mktime(0, 0, 0, $m, 1, $year));
    $first_day = explode(" ",$time);
    $time = $first_day[1];
//create the links to next and previous months
    $next = $month+2;
    $x = $year;
//if month is 13 then new year
    if($next==13){
        $next=1;
        $x = $x+1;
    }
    $prev = $month;
    $y = $year;
//if month is 0, then previous year
    if($prev==0){
        $prev=12;
        $y=$y-1;
    }
    $calendar = "";
//Build the calendar with css
//links to next and previous month only for browser
if ($c_type=="1") {
		// encode links
		$link_left = $enc->crypt_url("tslice=$y-$prev");
		$link_right = $enc->crypt_url("tslice=$x-$next");
		// check if we have chats in prev and next mo
		$db->is_left_or_right("$y-$prev");
		$i_left = $db->result;
		$db->is_left_or_right("$x-$next");
		$i_right = $db->result;
	}
	else {
		$i_left=0;
		$i_right=0;
	}
    $calendar .='
	
      	
        |  |  |  | 
      	
        |   | 
        
        | ';
if ($i_left!=0) { $calendar.='<<<'; }
$verb_date = "$year-$m-1";
	    $calendar.=' | '.verbose_date($verb_date,$months_names,$weekdays,false,true).' | ';
	  if ($i_right!=0) { $calendar.='>>>'; }
	    $calendar.=' |  
            	';
               
    //checks for leap years and add 1 to February
    if(($year % 4 =="") && ($month==1)){
        $days_in_month=$days_in_month+1;
    }
    else{
        $days_in_month=$days_in_month;
    }
    $new_time="";
     
    //find how many blank spaces at beginning of the month
     
    foreach($days_array as $key=>$value){
     
        if($value == $time){
            $new_time .= $key+1;
        }
        else{
            $new_time .="";
        }
    }
     
    //loop through the days in the month
	$c=0;
    for($k=1;$k<($days_in_month+$new_time);$k++){   
	$c++;
	if ($c==1) { $calendar.='| '.$cal_days[$lang][1].' | '.$cal_days[$lang][2].' | '.$cal_days[$lang][3].' | '.$cal_days[$lang][4].' | '.$cal_days[$lang][5].' | '.$cal_days[$lang][6].' | '.$cal_days[$lang][7].' |  '; }
 
            //blank space
     
        if($k<$new_time){
            $calendar.=''; $c=0; }
    }
    $calendar .= '| ';
            continue;
        }
         
        //start the actual days
              
        $n = $k-$new_time+1;
        if(in_array($n,$days)){
	
	if ($c_type=="1") {
			$to_base = $enc->crypt_url("tslice=$year-$m-$n");
			$loc_orign="";
		}
		elseif($c_type=="2") {
			$to_base = $enc->crypt_url("tslice=$year-$m-$n&peer_name_id=$name_peer&peer_server_id=$server_peer");
			$loc_orign="&loc=2";
		}
	    if ($selected==$n) { $bgcolor = 'bgcolor="#6daae7"'; } else { $bgcolor=""; }
            $calendar .= ' | '.$n.'';   
        }
        else{
            $calendar .= ' | '.$n.'';
        }     
	if ($c==7) { $calendar.=' |  |  | 
      	
        |  |  |  | 
    	
        
	';
    return($calendar);
}
function check_thread($db,$peer_name_id,$peer_server_id,$at,$xmpp_host,$dir=NULL) {
	#adjust this hours as needed, we assume if chat is +/- 1 hour on the edge of day, then chat is related
	if ($dir=="1") {
		$day="+1 day";
		$bhour="00:00:00";
		$ehour="00:30:00";
	}
	elseif($dir=="2"){
		$day="-1 day";
		$bhour="23:30:00";
		$ehour="23:59:59";
	}
	$get_date = date("Y-n-j", strtotime($day, strtotime(date("$at"))));
	$db->check_thread($get_date,$peer_name_id,$peer_server_id,$bhour,$ehour);
	if ($db->result > 0) {
			return true;
		}
		else{
			return false;
	}
	return false;
}
function check_rpc_server($rpc_arr,$rpc_port) {
	foreach($rpc_arr as $rpc_host) {
		// assume if response time is greater then 1 second RPC server is down
		$fp=fsockopen("$rpc_host", $rpc_port, $errno, $errstr, 1);
		if ($fp!=false) {
			return $rpc_host;
		}
	
	}
	return false;
	
}
function debug($debug=false,$string) {
	if ($debug===true) {
		
		print "".htmlspecialchars($string)."
";
	}
	return;
}
function message_processor($tslice,$server_name,$start,$nickname,$result_messages,$db,$html,$enc,$token,$split_line,$lang_pack,$lang,$spec_mark,$e_string,$to_base_prev,$to_base_next) {
	/* 
		This function perform message processing for message archives
		tslice - date of chat
		server_name - name of server
		start - from what point of time of day should chat be displayed
		nickname - peer nickname
		result_messages - array of messages to be parsed
		db - database object
		html - html object
		enc - encryption object
		token - owner name
		split_line - config option
		lang_pack - array of translations
		lang - language pack
		spec_mark - marker used to distinguish what we are doing
		e_string - url 
	*/
	// Check if user have set up OwnName
	$db->get_own_name();
	if ($db->result->own_name) {
			$own_name = $db->result->own_name;
		}
		else{
			$own_name = false;
	}
	// Main loop
	foreach($result_messages as $entry) {
		// always get resource_id if message is type of groupchat
		if ($entry[type] !== "groupchat") {
				if ($resource_last !== $entry[peer_resource_id]) {
					if ($db->get_resource_name($entry[peer_resource_id]) === false) {
						return false;
					}
					$resource = $db->result->resource_name;
				}
			
			}
			else{
				if ($db->get_resource_name($entry[peer_resource_id]) === false) {
						return false;
				
				}
				$resource = $db->result->resource_name;
		}
		$resource_last = $entry[peer_resource_id];
                $licz++;
		// marking messages
		if ($entry["type"] === "chat" OR $entry["type"] == "") {
                		if ($entry["direction"] === "to") { 
		
						$col="main_row_a"; 
					} 
					else { 
						$col="main_row_b"; 
				}
			}
			elseif($entry["type"] === "error") {
					$col="main_row_error";
				}
			elseif($entry["type"] === "normal") {
					$col="main_row_message";
				}
			elseif($entry["type"] === "headline") {
					$col="main_row_headline";
			}
		
                $ts = strstr($entry["ts"], ' ');
                // time calc 
                $pass_to_next = $entry["ts"];
                $new_d = $entry["ts"];
                $time_diff = abs((strtotime("$old_d") - strtotime(date("$new_d"))));
                $old_d = $pass_to_next;
                // end time calc
                if ($time_diff>$split_line AND $licz>1) { 
                                
				$in_minutes = round(($time_diff/60),0);
                                $html->set_body('
							| '.verbose_split_line($in_minutes,$lang_pack[7],$lang_pack[8]).' 
 | 
						');
		}
		// check if chat is continuation from previous day (work only for calendar view)
		if ($to_base_prev !== NULL) {
			if ($ts_mark!="1" AND substr($ts, 0 , strpos($ts, ":")) == 00 ) {
				if ( check_thread($db,$talker,$server,$tslice,$xmpp_host,2) === true) {
				
						$html->set_body('| '.$lang_pack[0].' | 
');
				}
				// check only first line
				$ts_mark="1";
			}
		}
		// run code only if type is not groupchat
		if ($entry["type"] !== "groupchat") {
			// setting subject
			if ($col==="main_row_message" OR $col==="main_row_headline") {
				if ($entry["subject"]) {
						$subject = ": ".$entry["subject"];
					}
					else{
						unset($subject);
				}
		
			}
			// add line in case of special message
			if ($col==="main_row_message") {
				$html->set_body('| '.$lang_pack[1].' '.htmlspecialchars($subject).' | 
');
			}
			if ($col==="main_row_error") {
				$html->set_body('| '.$lang_pack[2].' | 
');
				
			}
			if ($col==="main_row_headline") {
				$html->set_body('| '.$lang_pack[3].' '.htmlspecialchars($subject).' | 
');
			}
		}
		// calculate chat direction, whether to display nick...
                if ($entry["direction"] == "from") {
                                $out=$nickname;
                                $tt=$tt+1;
                                $aa=0;
                        
			}
                        else{
                                $out = $token;
                                $aa=$aa+1;
                                $tt=0;
                        
			}
		// timestamp, beginning of the chatline
		if ($entry["type"] !== "groupchat") {
                		$html->set_body('| '.$ts.'');
			}
			else{
				if ($out!==$token) {
					// colorize
					if ($resource_group === $resource OR !$resource_group) {
							if (!$col) {
								$col = "main_row_group_to";
							
							}
							$col=$col;
						
						}
						else{
							if($col === "main_row_group_from") {
								$col="main_row_group_to";
							}
							else{
								$col="main_row_group_from";
							}
						
					}
					$html->set_body(' | 
| '.$ts.'');
				}
		}
		// different bahaviour for groupchat and other messages
		if ($entry["type"] !== "groupchat") {
                
				if ($aa<2 AND $tt<2) {
                                		$html->set_body(' | ');
						if ($out === TOKEN) {
								// display of Own Name
								if ($own_name !== false) {
										$html->set_body(cut_nick(htmlspecialchars($own_name)));
									}
									else{
										$html->set_body(cut_nick(htmlspecialchars($out)));
								}
							}
							else{
								$html->set_body(cut_nick(htmlspecialchars($out)));
						}
						$html->set_body('');
                                		if ($out !== $token) {
								if ($spec_mark === false) {
                                						$html->set_body(' ');
                                		$here = "1";
                        		}
                        		else {
                                		$html->set_body('');
							
									}
									else{
										$html->set_body('
 
 
											'.cut_nick(htmlspecialchars($server_name)).'');
								}
                                		}
                                		$html->set_body(' | -');
						$here = "0";
                        
				}
			}
			else{
				// do not display own chats sent to MUC. Here resource is actualy nickname as MUC standard specify
				if ($out !== $token) {
						if ($resource_group !== $resource) {
								// if message is sent without resource, that must be channel message, advise user.
								if ($resource === "") {
									$resource = $lang_pack[5];
								
								}
								$html->set_body(' | MUC: '.cut_nick($out).' ');
								$here = "1";
								$resource_group = $resource;
						
							}
							else{
								$html->set_body('
 '.cut_nick(htmlspecialchars($resource)).' | -');
								$here = "0";
							
							}
					
					}
					else{
						$here = "0";
					
					}
		}
		// process body part, do not show chat if message is type of groupchat
		// this is sadly funny i write this 'if' and i dont know what exacly it do :/
		if ($out !== $token OR $entry["type"] !== "groupchat") {
			// prepare body
                	$new_s = htmlspecialchars($entry["body"]);
                	$to_r = array("\n");
                	$t_ro = array(" | 
");
                	$new_s = str_replace($to_r,$t_ro,$new_s);
                	$new_s = wordwrap($new_s,107,"
",true);
                	$new_s = new_parse_url($new_s);
                	$html->set_body(''.$new_s.'');
			// generate mylink only on selected lines
                	if ($here==="1") { 
					$lnk = $enc->crypt_url("tslice=$tslice&peer_name_id=$entry[peer_name_id]&peer_server_id=$entry[peer_server_id]");
					$to_base2 = $enc->crypt_url("tslice=$tslice&peer_name_id=$entry[peer_name_id]&peer_server_id=$entry[peer_server_id]&ismylink=1&linktag=$licz&lnk=$lnk&strt=$start");
					$html->set_body(' | '.$lang_pack[6].'');
			
				} 
				else { 
					$html->set_body(' | ');
				
				}
                	if ($t=2) { $c=1; $t=0; } // WTF!?
                
			$html->set_body(' | 
');
		}
	}
	
	$html->set_body('');
	// Check thread. Work only for calendar view.
	if ($to_base_next !== NULL) {
		if (substr($ts, 0 , strpos($ts, ":")) == 23 AND date("Y-n-j") !== $tslice) {
			if ( check_thread($db,$talker,$server,$tslice,$xmpp_host,1) === true) {
		
				$html->set_body('| '.$lang_pack[9].' | 
');
			
			}
		}
	}
	return true;
}
function is_language_supported($l_query,$language_support,$l_key = 0, $return_val = false) {
	
	while (array_keys($language_support)) {
		$lang_key = key($language_support);
		if ($l_query === $language_support[$lang_key][$l_key]) {
			if ($return_val === true) {
					return $language_support[$lang_key][0];
				}
				else {
					return true;
			}
		
		}
		array_shift($language_support);
	}
	return false;
}
?>