<?php
 	/**************************************************************************\
	* AngleMail - E-Mail Message Processing Functions for MIME and Display	   *
	* This file written by Angelo "Angles" Puglisi <angles@aminvestments.com>  *
	* Copyright (C) 2001-2002 Angelo "Angles" Puglisi						   *
	* ------------------------------------------------------------------------ *
	* This Program is customized on Jananese environment(only japanese).	   *
	* Copyright (C) 2003 Kazuya Nouchi										   *
	* ------------------------------------------------------------------------ *
	* This is not part of phpGroupWare, but is used by phpGroupWare.           * 
	* http://www.phpgroupware.org/                                             * 
	* ------------------------------------------------------------------------ *
	* This program is free software; you can redistribute it and/or modify it  *
	* under the terms of the GNU Lesser General Public License as published    *
	* by the Free Software Foundation; either version 2.1 of the License, or   *
	* any later version.                                                       *
	\**************************************************************************/
  
	/* $Id: class.mail_msg_display_ja.inc.php,v 1.1.10.3 2004/12/04 10:20:43 kazuyan Exp $ */
	
class mail_msg_display_ja extends mail_msg_display
{
	var $codecv;
	function mail_msg()
	{
		parent::mail_msg();
		if (!is_object($GLOBALS['phpgw']->codecv) || $GLOBALS['phpgw']->codecv->lang != 'ja')
		{
			$this->codecv = CreateObject('phpgwapi.codecv');
		}
		else
		{
			$this->codecv = &$GLOBALS['phpgw']->codecv;
		}
	}
	
	// ----  High-Level Function To Get The Subject String  -----
	function get_subject($msg, $desired_prefix='Re: ')
	{
		$subject = parent::get_subject($msg, $desired_prefix);
		$subject = $this->htmlspecialchars_decode($subject);
		$subject = $this->codecv->out2in($subject);
		return $subject;
	}
	
	function make_part_clickable($part_nice, $msgball)
	{
		$not_set = $this->not_set;
		
		// Part Number used to request parts from the server
		$m_part_num_mime = $part_nice['m_part_num_mime'];
		
		$part_name = $part_nice['ex_part_name'];
		
		// make a URL to directly access this part
		if ($part_nice['type'] != $not_set)
		{
			$url_part_type = $part_nice['type'];
		}
		else
		{
			$url_part_type = 'unknown';
		}
		if ($part_nice['subtype'] != $not_set)
		{
			$url_part_subtype = $part_nice['subtype'];
		}
		else
		{
			$url_part_subtype = 'unknown';
		}
		if ($part_nice['encoding'] != $not_set)
		{
			$url_part_encoding = $part_nice['encoding'];
		}
		else
		{
			$url_part_encoding = 'other';
		}
		$part_name = $this->codecv->out2in($this->decode_header_string($part_name));
		// make a URL to directly access this part
		$url_part_name = urlencode($part_name);
		// ex_part_href
		$ex_part_href = $GLOBALS['phpgw']->link(
			'/index.php',
			'menuaction=email.boaction.get_attach'
			.'&'.$msgball['uri'].'&msgball[part_no]='.$m_part_num_mime
			.'&type=' .$url_part_type
			.'&subtype=' .$url_part_subtype
			.'&name=' .$url_part_name
			.'&encoding=' .$url_part_encoding); 
		// Make CLICKABLE link directly to this attachment or part
		$href_part_name = $part_name;
//		$href_part_name = $this->decode_header_string($part_name);

		// ex_part_clickable
		$ex_part_clickable = '<a href="'.$ex_part_href.'">'.$href_part_name.'</a>';
		// put these two vars in an array, and pass it back to the calling process
		$click_info = Array();
		$click_info['part_href'] = $ex_part_href;
		$click_info['part_clickable'] = $ex_part_clickable;
		return $click_info;
	}

	/*!
	@function get_msg_list_display
	@abstract make an array containing all necessary data to display an "index.php" type list of mesasages
	@param $folder_info : array : (OPTIONAL) array elements as defined in return from function 
	  $this->get_folder_status_info() . This is primarily a time saver, if you already have the data, then pass it, 
	  else this function will obtain the data for itself.
	@param $folder_info : array of integers (OPTIONAL) integers representing a list of message numbers we 
	  should display, pass this data if you have search results to show, for example. If this is not present,
	  then this function get a numbered array list of all message numbers in that folder, sorted and ordered
	  according to preferences and/or user submitted page view args.
	@result array 
		first_item	boolean, flag indicating this is the first item in the array, the first message
				to display, states the obvious, but the index tpl uses it to show a form tag only once
		back_color	used in html UI's to alternate the color or each row of data
		has_attachment	attachment dection code has determined that this message has attachment(s)
				which tells the UI to show the user something, like a paperclip image.
		$msgnum	the number the mail server has assigned this message, used for fetching 
		subject		message subject text suitable for display, text only
		subject_link	URL that will request this message from the server, use with "subject" to make an HREF
		size		message size suitable for display
		is_unseen	this message has NOT yet been viewed by the client
		from_name	Part 1 of 2 of the From String to show the user. This part 1 is the "personal"
				data of the From person if it's available, if not we have no choice but to show
				the plain address of the from person.
		display_address_from	Part 2 of 2 of the From String to show the user. This part 2 contains
				any additional info the user prefers to see in the From String, which can be either
				(a) the plain address of the From person, or
				(b) the plain address of the ReplyTo header address
				According to user's preferences and considering what data is available
				to fulfill those user prefs
		who_to		Target address to send messages to when trying to "reply" to the author.
				Standard way to handle this is:
				(1) if ReplyTo is specified in the email header, then use it as the reply target
				(2) if no ReplyTo is specified, then we use the email address of the From person
				as the reply target. A seperate ReplyTo header address is optional when authoring
				a message, but it clearly states the intent of the "From person" that replying to the
				mail should NOT result in mail being sent to that "From person"'s address, so that
				intent SHOULD be honored.
				Another example: Quite often mailing lists use this header to make the
				"From" the person who sent the message to the list, and when you click "reply"
				the "ReplyTo" header indicates the mail should be sent to the list, NOT the
				person in the "From" header.
				Used to make the From String into a clickable HREF,
				which will produce a blank Compose Mail page with the To address filled targeted
				to this "who_to" value. This is different from a "reply to button" because no part
				of the original mail is included in the resulting Compose Mail page.
		from_link	URL that will produce an empty Compose New Mail page with the To address
				already filled in, which address is the determination made in the "who_to" logic
		msg_date	If the message arrived more than 1 day ago, this will be a date only.
				If the message arrived within one day, this will be the time of arrival with NO date.
	@discussion ?
	@access : private
	*/
	function get_msg_list_display($folder_info='', $msgball_list='')
	{
		$acctnum = $folder_info['fldball']['acctnum'];
		if (!isset($acctnum) || $acctnum == '')
			$this->get_acctnum();
		$server_type = $this->get_pref_value('mail_server_type', $acctnum);
		if ($server_type == 'pop3' || $server_type == 'pop3s')
		{
			$sort = (int)$this->get_arg_value('sort', $acctnum);
			$order = (int)$this->get_arg_value('order', $acctnum);
			if ($sort == 1 && $order == 1)
			{
				$ex_folder = $folder_info['fldball']['folder'];
				if (($this->session_cache_enabled == True)
					&& (isset($this->ref_SESSION['phpgw_session']['phpgw_app_sessions']['email']['dat'][$acctnum]['msgball_list'][$ex_folder]['msgball_list'])))
				{
					$msgball_list =& $this->ref_SESSION['phpgw_session']['phpgw_app_sessions']['email']['dat'][$acctnum]['msgball_list'][$ex_folder]['msgball_list'];
				}
				else
				{
					$msgball_list = $this->get_msgball_list($acctnum, $ex_folder);
				}
				$ctr = count($msgball_list);
				for ($i = 0;$i < $ctr; $i++)
				{
					$this_loop_msgball = $this->ball_data_parse_str($msgball_list[$i]);
					$hdr_envelope = $this->phpgw_header($this_loop_msgball);
					$tmp_msgball_list[] = array(
						'raw_msg_date'	=> $hdr_envelope->udate,
						'msgball'		=> $msgball_list[$i]
					);
				}
				usort($tmp_msgball_list, array('mail_msg_display_ja', 'cmp'));
				unset($msgball_list);
				for ($i = 0;$i < $ctr; $i++)
				{
					$msgball_list[$i] = $tmp_msgball_list[$i]['msgball'];	
				}				
			}
		}		
		$msg_list_display = parent::get_msg_list_display($folder_info, $msgball_list);
		$ctr = count($msg_list_display);
		for ($i = 0;$i < $ctr; $i++)
		{
			$msg_list_display[$i]['from_name'] = $this->codecv->out2in($msg_list_display[$i]['from_name']);
		}
		return $msg_list_display;
	}
	function cmp ($a, $b) {
    	return strcmp($b['raw_msg_date'],$a['raw_msg_date']);
	} 
	/*!
	@function phpgw_header
	@abstract wrapper for IMAP_HEADER, phpgw supplies the nedessary stream arg and mail_dcom reference
	@param $msgball (typed array)
	@result returns the php IMAP_HEADER data
	@discussion Wrapper supplies the needed mailsvr_stream arg to IMAP_HEADER. 
	Message Information: THE MESSAGE'S HEADERS RETURNED AS A STRUCTURE. 
	The data communications object (class mail_dcom) is supplied by the class. 
	CACHE NOTE if $this->session_cache_extreme is True, then this data is cached and 
	manipulated by the "extreme" caching code, which will pop a cached "phpgw_header" out 
	of cache if the message is moved to another folder, and manually clear a cached "phpgw_header" 
	items flag from "unseen" or "recent", if necessary, if the message is read, and put the updated 
	"phpgw_header" item back in cache, with no need to contact the mailserver about this. Eventhough 
	we still need to contact the mail server to get the body, by manually clearing the flag, if necssary, as 
	described above, then when the user goes back to the message list after reading the message, 
	it is possible that ALL information required to make that index page is "fresh" in local cache, 
	and NO login to the mailserver is done in that case. Situations where ALL the necessary data 
	is not in the cache are as follows, if the user deleted or moved ONE message, for example, it 
	may be possible that the index page needs to contact the mailserver to get one additional "phpgw_header" 
	(and also one additional "msg_structure") item to fill out the message list page. If the user had already 
	viewed the index page that had that message, such as paging forward and then backwards thru the 
	message list, the the single message that *was* on the next message list page that is now on the *current* 
	message list page, would already be in the cache. If $this->session_cache_extreme is False, 
	then caching is NOT used on this data.
	*/
	function phpgw_header($msgball='')
	{
		$data = parent::phpgw_header($msgball);	
		if (!$data->from)
			return $data;
		$data->from[0]->personal = $this->decode_header_string($data->from[0]->personal);
		$data->from[0]->personal = $this->codecv->out2in($data->from[0]->personal);
		$data->from[0]->personal = ereg_replace("^\"|\"$", '', $data->from[0]->personal);
		$data->fromaddress = $this->decode_header_string($data->fromaddress);
		$data->fromaddress = $this->codecv->out2in($data->fromaddress);
		for ($i = 0;$i < count($data->to); $i++)
		{
			$data->to[$i]->personal = $this->decode_header_string($data->to[$i]->personal);
			$data->to[$i]->personal = $this->codecv->out2in($data->to[$i]->personal);
		}
		for ($i = 0;$i < count($data->cc);$i++)
		{
			$data->cc[$i]->personal = $this->decode_header_string($data->cc[$i]->personal);
			$data->cc[$i]->personal = $this->codecv->out2in($data->cc[$i]->personal);
		}
		for ($i = 0;$i < count($data->bcc);$i++)
		{
			$data->bcc[$i]->personal = $this->decode_header_string($data->bcc[$i]->personal);
			$data->bcc[$i]->personal = $this->codecv->out2in($data->bcc[$i]->personal);
		}
		for ($i = 0;$i < count($data->reply_to);$i++)
		{
			$data->reply_to[$i]->personal = $this->decode_header_string($data->reply_to[$i]->personal);
			$data->reply_to[$i]->personal = $this->codecv->out2in($data->reply_to[$i]->personal);
		}
		$data->subject = $this->decode_header_string($data->subject);
		$data->subject = $this->codecv->out2in($data->subject);
		return $data;
	}
	/*!
	@function phpgw_fetchbody
	@abstract FETCHBODY get a portion, via MIME part number, of a message body, not the entire body.
	@param $msgball (typed array) 
	@param $flags (defined int) options passed to the mailserver with the php FETCHBODY command. 
	(Not related to a message flag like "unseen", this is an optional argument for the mail server.) 
	@author Angles
	*/
	function phpgw_fetchbody($msgball='', $flags='')
	{
		//return $this->codecv->out2in(parent::phpgw_fetchbody($msgball, $flags));
		$body = parent::phpgw_fetchbody($msgball, $flags);
		if ($body)
		{
			$meta_data['msgball'] = $msgball;
			$meta_data['phpgw_fetchbody'] = $this->codecv->out2in($body);
			$this->save_session_cache_item('phpgw_fetchbody', $meta_data, $this->get_acctnum());
			return $meta_data['phpgw_fetchbody'];
		}
		return False;
	}
	// SUB-FUNCTION - do not call directly, used by "encode_header()"
	function encode_ISO2022JP_word($string)
	{
		$base64_prefix = '=?' . lang('outcharset') . '?B?';
		$base64_suffix = '?=';
		$new_str = '';

		if ($this->codecv->get_charcode($string) == "US-ASCII")
		{
			return $string;
		}
		else
		{
			$enstring = $string;
		}

		$maxlen = 75 - 7 - strlen(lang('outcharset'));
		$maxlen -= $maxlen % 4;
		$enstring = $this->codecv->mb_chunk_split($enstring, $maxlen, "\r\n");
		$array_str = explode("\r\n", rtrim($enstring));
		while (list($idx, $enstring) = each($array_str))
		{
			$enstring = base64_encode($this->codecv->in2out($enstring));
			if ($idx == 0)
			{
				$array_str[$idx] = $base64_prefix . $enstring . $base64_suffix;
			}
			else
				$array_str[$idx] = "\t" . $base64_prefix . $enstring . $base64_suffix;
		}
		$new_str = implode($array_str, "\r\n");

		return  $new_str;
	}
	// encode email headers as per rfc2047, non US-ASCII chars in email headers
	// basic idea is to qprint any word with "header-unfriendly" chars in it
	// then surround that qprinted word with the stuff specified in rfc2047
	// Example:
	//  "my //name\\ {iS} L@@T" <leet@email.com>
	// that email address has "header-unfriendly" chars in it
	// this function would encode it suitable for email transport
	function encode_header($data, $space_encode=False)
	{
		// check extra email address format
		$validate = createobject('phpgwapi.validator');
		if (preg_match_all('|\"([^\"]*)\"\s+<([^>]*)>|', $data, $regs))
		{
			for($i = 0;$i < count($regs[1]); $i++)
			{
				$str_replace = str_replace(' ', chr(0), $regs[1][$i]);
				$data = str_replace($regs[1][$i], $str_replace, $data);
				if (!$extra_email && $validate->is_email($regs[2][$i]))
					$extra_email = True;
			}
		}
		elseif ($space_encode)
			$data = str_replace(' ', chr(0), $data);
		//$words[] = $data;
		$words = explode(' ', $data);
		
		for($i=0; $i<count($words); $i++)
		{
			//echo 'words['.$i.'] in loop: '.$words[$i].'<br>';
			$words[$i] = str_replace(chr(0), ' ', $words[$i]);
			// my interpetation of what to encode from RFC2045, RFC2047, and RFC2822
			// all these chars seem to cause trouble, so encode them
			if (preg_match('/'
				. '['.chr(1).'-'.chr(31).']'
				. '['.chr(33).'-'.chr(38).']'
				.'|[\\'.chr(39).']'
				.'|['.chr(40).'-'.chr(46).']'
				.'|[\\'.chr(47).']'
				.'|['.chr(61).'-'.chr(62).']'
				.'|['.chr(64).']'
				.'|['.chr(91).'-'.chr(94).']'
				.'|['.chr(96).']'
				.'|['.chr(123).'-'.chr(255).']'
				.'/', $words[$i]))
			{
				/*
				// qprint this word, and add rfc2047 header special words
				$len_before = strlen($words[$i]);
				echo 'words['.$i.'] needs encode: '.$words[$i].'<br>';
				$words[$i] = imap_8bit($words[$i]);
				echo 'words['.$i.'] AFTER encode: '.$words[$i].'<br>';
				// php may not encode everything that I expect, so check to see if encoding happened
				$len_after = strlen($words[$i]);
				if ($len_before != $len_after)
				{
					// indeed, encoding did happen, add rfc2047 header special words
					$words[$i] = $qprint_prefix .$words[$i] .$qprint_suffix;
				}
				*/
				if ($extra_email && preg_match('|\"([^\"]*)\"|',$words[$i],$matches))
					$words[$i] = $matches[1];
				else
					unset($matches);
				// qprint this word, and add rfc2047 header special words
				//echo 'words['.$i.'] needs encode: '.$words[$i].'<br>';
				$words[$i] = $this->encode_ISO2022JP_word($words[$i]);
				//echo 'words['.$i.'] AFTER encode: '.$words[$i].'<br>';
				if (is_array($matches))
					$words[$i] = '"'.$words[$i].'"';	
			}
		}
		
		// reassemble the string
		$encoded_str = implode(' ',$words);
		return $encoded_str;
	}
	// ----  Make Address accoring to RFC2822 Standards  -----
/*	function make_rfc2822_address($addy_data, $html_encode=True)
	{
		//echo '<br>'.$this->htmlspecialchars_encode(serialize($addy_data)).'<br>'.'<br>';
		
		if ((!isset($addy_data->mailbox)) && (!$addy_data->mailbox)
		&& (!isset($addy_data->host)) && (!$addy_data->host))
		{
			// fallback value, we do not want to sent a string like this "@" if no data if available
			return '';
		}
		// now we can continue, 1st make a simple, plain address
		// RFC2822 allows this simple form if not using "personal" info
		$rfc_addy = $addy_data->mailbox.'@'.$addy_data->host;
		// add "personal" data if it exists
		if (isset($addy_data->personal) && ($addy_data->personal))
		{
			// why DECODE when we are just going to feed it right back into a header?
			// answer - it looks crappy to have rfc2047 encoded personal info in the to: box
			$personal = $this->decode_header_string($addy_data->personal);
			$personal = $this->codecv->out2in($personal);
			$personal = ereg_replace("^\"|\"$", '', $personal);
			// need to format according to RFC2822 spec for non-plain email address
			$rfc_addy = '"'.$personal.'" <'.$rfc_addy.'>';
			// if using this addy in an html page, we need to encode the ' " < > chars
			if ($html_encode)
			{
				//$rfc_addy = $this->htmlspecialchars_encode($rfc_addy);
				$endq = $this->htmlspecialchars_encode('"');
				$engt = $this->htmlspecialchars_encode('<');
				$enlt = $this->htmlspecialchars_encode('>');
				$enaddy = $this->htmlspecialchars_encode($addy_data->mailbox.'@'.$addy_data->host);
				$rfc_addy = $endq . $personal . $endq . ' ' . $engt . $enaddy . $enlt;
				//$rfc_addy = $this->htmlspecialchars_encode($rfc_addy);
				//NOTE: in rfc_comma_sep we will decode any html entities back into these chars
			}
		}
		return $rfc_addy;
	}*/
	
	function decode_header_string_orig($string)
	{
		if($string)
		{
			$pos = strpos($string,"=?");
			if(!is_int($pos))
			{
				return $string;
			}
			// save any preceding text
			$preceding = substr($string,0,$pos);
			$end = strlen($string);
			// the mime header spec says this is the longest a single encoded word can be
			$search = substr($string,$pos+2,$end - $pos - 2 );
			$d1 = strpos($search,"?");
			if(!is_int($d1))
			{
				return $string;
			}
			$charset = strtolower(substr($string,$pos+2,$d1));
			$search = substr($search,$d1+1);
			$d2 = strpos($search,"?");
			if(!is_int($d2))
			{
				return $string;
			}
			$encoding = substr($search,0,$d2);
			$search = substr($search,$d2+1);
			$end = strpos($search,"?=");
			if(!is_int($end))
			{
				return $string;
			}
			$encoded_text = substr($search,0,$end);
			$rest = substr($string,(strlen($preceding.$charset.$encoding.$encoded_text)+6));
			$preceding = ereg_replace("^[ \t]+", '', $preceding);		// head space & head tab char removed
			if(strtoupper($encoding) == "Q")
			{
				$decoded = $this->qprint(str_replace("_"," ",$encoded_text));
			}
			if (strtoupper($encoding) == "B")
			{
				$decoded = base64_decode($encoded_text);
			}
			return $preceding . $decoded . $this->decode_header_string($rest);
		} 
		else
		{
			return $string;
		}
	}
	/*!
	@function qprint
	@abstract Decode quoted-printable encoded text to ASCII
	@result string
	@discussion FOR SOME REASON this function originally did 2 extra things 
	before using the php "quoted_printable_decode" command.  First, it would 
	change any underscores "_" to a space, and second, it would change the 
	sequence "=CRLF" to nothing, in other words erasing that. THIS IS NOW 
	COMMENTED OUT until it is understood why this function was doing 
	that. Now this function simply returns "quoted_printable_decode" output. 
	Note the IMAP module has a function called "imap_qprint", these 2 php 
	functions do the same thing except that "quoted_printable_decode" does 
	not require the IMAP module compiled into php.
	@author previous authors, Angles
	*/
	function qprint($string)
	{
		return $this->codecv->out2in(parent::qprint($string));
	}
	/*!
	@function get_arg_value
	@abstract Obtain the value of a given class variable, will handoff to helper functions if necessary.
	@param $arg_name  (string)
	@param $acctnum  (int) OPTIONAL 
	@result (string, int, or array)
	@author Angles
	@discussion Some class variables, such as "mailsvr_namespace", have functions dedicated only to determining their value. 
	In these cases this function will hand off the request directly to that specialized function. In other cases the 
	class variable desired is a simple variable and its value is returned.
	@access public
	*/
	function get_arg_value($arg_name='',$acctnum='')
	{
		$result = parent::get_arg_value($arg_name, $acctnum);
		if (!is_object($GLOBALS['phpgw']->browser))
			$GLOBALS['phpgw']->browser = CreateObject("phpgwapi.browser");
		if ($arg_name == 'name')
		{
			if ($GLOBALS['phpgw']->browser->is_windows())
			{
				if (!$GLOBALS['phpgw']->browser->is_opera())
					$result = $this->codecv->euctosjis($result);
			}
			elseif ($GLOBALS['phpgw']->browser->is_mac())
			{
				$result = $this->codecv->euctojis($result);
			}
		}
		return $result;
	}

	/*!
	@function ensure_one_urlencoding
	@abstract TESTING - make sure folder arg is urlencoded ONCE only
	@param $str (string) 
	@author Angles
	*/
	function ensure_one_urlencoding($str='')
	{
		$str = parent::ensure_one_urlencoding($str);
		if ($this->codecv->get_charcode($str) != 'US-ASCII')
			$str = urlencode($str);
		return $str;
	}
	
	/*!
	@function decode_rfc_header
	@abstract Email header must have chars within US-ASCII limits, any other chars must be encoded, this function DECODES said text.
	@result string
	@author Angles
	@discussion Email header must have chars within US-ASCII limits, any other chars must 
	be encoded according to RFC2822 spec, this function DECODES said chars, usually one word is encoded individually. 
	Uses regex to handle either base64 or quoted-printable encoded email headers, 
	does not care about the specified charset, just decodes based on Q or B encoding key.
	@syntax Non-us-ascii chars in email headers MUST be encoded using the special format 
	=?charset?Q?word?=
	=?charset?B?word?=
	currently only qprint and base64 encoding is specified by RFCs, represented by the Q or B, 
	which can be upper OR lower case.
	*/
	function decode_rfc_header($data)
	{
		// SAME FUNCTIONALITY as decode_header_string()  (but Faster, hopefully)
		// non-us-ascii chars in email headers MUST be encoded using the special format:  
		//  =?charset?Q?word?=
		// currently only qprint and base64 encoding is specified by RFCs
		if (ereg("=\?.*\?(Q|q)\?.*\?=", $data))
		{
			$data = ereg_replace("=\?.*\?(Q|q)\?", '', $data);
			$data = ereg_replace("\?=", '', $data);
			$data = $this->qprint(str_replace("_"," ",$data));
		}
		if (ereg("=\?.*\?(B|b)\?.*\?=", $data))
		{
			$data = $this->decode_header_string_orig($data);
			$data = $this->codecv->out2in($data);
		}
		return $data;
	}
	
	function make_rfc_addy_array($data)
	{
		$addy_array = parent::make_rfc_addy_array($data);
		for ($i = 0;$i < count($addy_array); $i++)
		{
			$personal = explode(' ', $addy_array[$i]['personal']);
			if (empty($personal[1]))
				continue;
			$personal[0] = $this->decode_header_string($personal[0]);
			$personal[1] = $this->decode_header_string($personal[1]);
			$addy_array[$i]['personal'] = $this->encode_header(implode(' ', $personal), True);
		}
		return $addy_array; 
	}
	
	/*!
	@function _image_on
	@abstract temp replacement for phpgwapi  image_on until it supports images in different dirs.
	@discussion Email themes have a group of similar looking images grouped into a directory with
	somewhat standard names that AngleMail understands as a themed image set. phpgwapi does not
	currently support subdirectories under the template images directory. Params are only to match the
	phpgw api function, we do not really use them. As of this writting, Feb 2003, images used for all themes,
	i.e. are not in a theme subdir but are used, are check and attach on the index page, they are not even
	sized, and, these are sized but not themed, on the message view page, are view_nofmt, view_formatted,
	view_headers, view_raw, and view_printable. Remember if these are themed they must be moved
	into the subdirs, all of them, even if they are copies, and removed from the main images dir, so it is
	obvious if they are group themed or not.
	@author Angles
	*/
	function _image_on($appname,$image,$extension='_on',$navbar=False)
	{
		if ($GLOBALS['phpgw']->browser->is_ie())
		{
			$prefer_ext = '.gif';				// for non support transparent png  		
		}
		else
		{
			switch ($GLOBALS['phpgw_info']['server']['image_type'])
			{
				case 1:							//GIF->JPG->PNG
				case 2:							//PNG->JPG
					$prefer_ext = '.png';
					break;
				default:						//GIF->JPG->PNG
					$prefer_ext = '.gif';
			}
		}			
		return $GLOBALS['phpgw_info']['server']['webserver_url'].'/'.$appname.'/templates/default/images'.'/'.$image.$prefer_ext;
	}
}

?>