function zem_contact($atts, $thing = '')
{
	global $sitename, $prefs, $production_status, $zem_contact_form, $zem_contact_from, $zem_contact_nonce, $zem_contact_error;

	extract(lAtts(array(
		'bcc'		=> '',
		'copysender'	=> 'no',
		'form'		=> '',
		'from'		=> '',
		'from_form'	=> '',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('contact'),
		'redirect'	=> '',
		'show_error'	=> 'yes',
		'show_input'	=> 'yes',
		'send_article'	=> 'no',
		'subject'	=> zem_contact_gTxt('email_subject', $sitename),
		'to'		=> '',
		'to_form'	=> '',
		'thanks'	=> graf(zem_contact_gTxt('email_thanks')),
		'thanks_form'	=> ''
	), $atts));

	if (!is_callable('mail'))
	{
		return ($production_status == 'live') ?
			zem_contact_gTxt('mail_sorry') :
			gTxt('warn_mail_unavailable');
	}

	if ($to_form)
	{
		$to_form = fetch_form($to_form);
		$to = parse($to_form);
	}

	if (!$to and $send_article == 'no')
	{
		return zem_contact_gTxt('to_missing');
	}

	$zem_contact_nonce = md5(uniqid(rand(), true));

	safe_insert('txp_discuss_nonce', "issue_time = now(), nonce = '$zem_contact_nonce'");

	$form = ($form) ? fetch_form($form) : $thing;

	if (empty($form))
	{
		$form = <<<form
<txp:zem_contact_text label="Name" /><br />
<txp:zem_contact_email /><br />
<txp:zem_contact_textarea /><br />
<txp:zem_contact_submit />
form;
	}

	$form = parse($form);

	if ($thanks_form)
	{
		$thanks = fetch_form($thanks_form);
	}

	$out = '';

	if (is_array($zem_contact_error) and count($zem_contact_error))
	{
		if ($show_error == 'yes')
		{
			$out .= n.'<ul class="zemError">';

			foreach ($zem_contact_error as $error)
			{
				$out .= n.t.'<li>'.$error.'</li>';
			}

			$out .= n.'</ul>';
		}

		$show_input = 'yes';
	}

	elseif (is_array($zem_contact_form) and ps('zem_contact_submit'))
	{
		/// load and check spam plugins/
		callback_event('zemcontact.submit');
		$evaluation =& get_zemcontact_evaluator();
		$clean = $evaluation->get_zemcontact_status();
		if ($clean != 0) {
			return zem_contact_gTxt('spam');
		}

		if ($from_form)
		{
			$from = parse($from_form);
		}

		$sep = !is_windows() ? "\n" : "\r\n";

		$msg = array();

		foreach ($zem_contact_form as $k => $v)
		{
			$msg[] = $k.': '.htmlspecialchars($v);
		}

	if ($send_article == 'yes') {
			global $thisarticle;
			$subject = $thisarticle['title'];
			$msg[] = $thisarticle['title'].' ('.permlinkurl($thisarticle).')'; // added permlink
		if ($thisarticle['excerpt']) {
			$exc = strip_tags($thisarticle['excerpt']); // added striptags
			$exc = str_replace("\t", '', $exc); // added strreplace
			$msg[] = trim($exc); // added trim
		}
		$bdy = strip_tags($thisarticle['body']); // same for these two lines
		$msg[] = str_replace("\t", '', $bdy);

		if (!ps('receiver')) {
			return zem_contact_gTxt('field_missing', zem_contact_gTxt('receiver'));
			$isError = "errorElement";
		}
		else
		{
			$to = ps('receiver');
		}
	}

		$msg = join("\n\n", $msg);
		$msg = str_replace("\r\n", "\n", $msg);
		$msg = str_replace("\r", "\n", $msg);
		$msg = str_replace("\n", $sep, $msg);

		if ($from)
		{
			$from  = $from;
			$reply = $zem_contact_from;
		}

		else
		{
			$from = $zem_contact_from;
			$reply = '';
		}

		if ($copysender == 'yes')
		{
			$bcc = $to;
			$to = $zem_contact_from;
		}

		$to      = strip_rn($to);
		$bcc     = strip_rn($bcc);
		$subject = strip_rn($subject);
		$from    = strip_rn($from);
		$reply   = strip_rn($reply);

		if ($prefs['override_emailcharset'])
		{
			$charset = 'ISO-8599-1';

			if (is_callable('utf8_decode'))
			{
				$to      = utf8_decode($to);
				$bcc      = utf8_decode($bcc);
				$subject = utf8_decode($subject);
				$msg     = utf8_decode($msg);
				$from    = utf8_decode($from);
				$reply   = utf8_decode($reply);
			}
		}

		else
		{
			$charset = 'UTF-8';
		}

		$headers = 'From: '.$from.
			($reply ? ($sep.'Reply-To: '.$reply) : '').
			($bcc ? ($sep.'Bcc: '.$bcc) : '').
			$sep.'X-Mailer: Textpattern (zem_contact_reborn)'.
			$sep.'Content-Transfer-Encoding: 8bit'.
			$sep.'Content-Type: text/plain; charset="'.$charset.'"';

		if (mail($to, $subject, $msg, $headers))
		{
			if ($redirect)
			{
				header('HTTP/1.1 303 See Other');
				header('Status: 303');
				header('Location: '.hu.$redirect);
				header('Connection: close');
			}

			else
			{
				$_POST = array();

				if ($show_input == 'yes')
				{
					if ($thanks)
					{
						return $thanks;
					}
				}
			}
		}

		else
		{
			$out .= graf(zem_contact_gTxt('mail_sorry'));
		}
	}

	if ($show_input == 'yes' and $send_article == 'no' or gps('zem_contact_send_article'))
	{
		if (ps('zem_contact_submit'))
		{
			$nonce = ps('zem_contact_nonce');

			if (empty($nonce))
			{
				$zem_contact_error[] = zem_contact_gTxt('field_missing');
				$isError = "errorElement";
			}

			else
			{
				safe_delete('txp_discuss_nonce', 'issue_time < date_sub(now(), interval 10 minute)');

				$rs = safe_row('*', 'txp_discuss_nonce', "nonce = '$nonce' and used = '0'");

				if ($rs)
				{
					safe_update('txp_discuss_nonce', "used = '1'", "nonce = '$nonce'");
				}

				else
				{
					$zem_contact_error[] = zem_contact_gTxt('form_expired');
				}
			}
		}

		return '<form method="post" id="zemContactForm" action="'.serverSet('REQUEST_URI').'">'.
			( $label ? n.'' : n.'<div>' ).
			( $label ? n.'' : '' ).
			$out.
			n.'<input type="hidden" name="zem_contact_nonce" value="'.$zem_contact_nonce.'" />'.
			$form.
			( $label ? (n.'') : (n.'</div>') ).
			callback_event('zemcontact.form'). // not sure, if it should be outside or inside the fieldset. What do you think, Stu?
			n.'</form>';
	}

	return '';
}

function zem_contact_text($atts)
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'break'		=> br,
		'default'	=> '',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('text'),
		'max'		=> 100,
		'min'		=> 0,
		'name'		=> '',
		'required'	=> 'yes',
		'size'		=> ''
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	$value = ps($name) ? ps($name) : $default;

	if ($value and $max)
	{
		$value = substr($value, 0, $max);
	}

	if (ps('zem_contact_submit') and $required == 'yes' and empty($value))
	{
		$zem_contact_error[] = zem_contact_gTxt('field_missing', $label);
		$isError = "errorElement";
	}

	elseif (ps($name) and $min and strlen($value) < $min)
	{
		$zem_contact_error[] = zem_contact_gTxt('min_warning', $label, $min);
		$isError = "errorElement";
	}

	elseif (ps($name))
	{
		$zem_contact_form[$label] = $value;
	}

	$size = ($size) ? ' size="'.(int)$size.'"' : '';
	$maxlength = ($max) ? ' maxlength="'.(int)$max.'"' : '';

        if ($required == 'yes')
        {
        return '<label for="'.$name.'" class="zemRequired'.$isError.' '.$name.'">'.$label.'</label>'.$break.
		'<input type="text" id="'.$name.'" class="zemRequired'.$isError.'" name="'.$name.'" value="'.htmlspecialchars($value).'"'.$size.$maxlength.' />';
         }
        else
        {
	return '<label for="'.$name.'" class="'.$name.'">'.$label.'</label>'.$break.
		'<input type="text" id="'.$name.'" name="'.$name.'" value="'.htmlspecialchars($value).'"'.$size.$maxlength.' />';
        }

}

function zem_contact_textarea($atts)
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'break'		=> br,
		'cols'		=> 58,
		'default'	=> '',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('message'),
		'max'		=> 10000,
		'min'		=> 0,
		'name'		=> '',
		'required'	=> 'yes',
		'rows'		=> 8
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	$value = ps($name) ? ps($name) : $default;

	if ($value and $max)
	{
		$value = substr($value, 0, $max);
	}

	if (ps('zem_contact_submit') and $required == 'yes' and empty($value))
	{
		$zem_contact_error[] = zem_contact_gTxt('field_missing', $label);
		$isError = "errorElement";
	}

	elseif (ps($name) and $min and strlen($value) < $min)
	{
		$zem_contact_error[] = zem_contact_gTxt('min_warning', $label, $min);
		$isError = "errorElement";
	}

	elseif (ps($name))
	{
		$zem_contact_form[$label] = $value;
	}

	if ($required == 'yes')
	{
	return '<label for="'.$name.'" class="zemRequired'.$isError.' '.$name.'">'.$label.'</label>'.$break.
		'<textarea id="'.$name.'" class="zemRequired'.$isError.'" name="'.$name.'" cols="'.$cols.'" rows="'.$rows.'">'.htmlspecialchars($value).'</textarea>';
	}
	else
	{
	return '<label for="'.$name.'" class="'.$name.'">'.$label.'</label>'.$break.
		'<textarea id="'.$name.'" name="'.$name.'" cols="'.$cols.'" rows="'.$rows.'">'.htmlspecialchars($value).'</textarea>';
	}
}

function zem_contact_email($atts)
{
	global $zem_contact_form, $zem_contact_from, $zem_contact_error;

	extract(lAtts(array(
		'default'	=> '',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('email'),
		'max'		=> 100,
		'min'		=> 0,
		'name'		=> '',
		'required'	=> 'yes',
		'break'		=> br,
		'size'		=> ''
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	$email = ps($name);

	if (ps('zem_contact_submit'))
	{
      if ($required == 'yes' and !empty($email)) {

		if (!preg_match('/^[\w._-]+@([\w-]+\.)+[\w-]+$/', $email))
		{
			$zem_contact_error[] = zem_contact_gTxt('invalid_email', $email);
			$isError = "errorElement";
		}

		elseif (preg_match("/@(.+)$/", $email, $match))
		{
			$domain = $match[1];
			$mx = 0;

			if (is_callable('getmxrr'))
			{
				$dummy = array();
				$mx = @getmxrr($domain, $mx);
			}

			if (!$mx and (@gethostbyname($domain) == $domain))
			{
				$zem_contact_error[] = zem_contact_gTxt('invalid_host', $domain);
				$isError = "errorElement";
			}

			else
			{
				$zem_contact_from = $email;
			}
		}

		else
		{
			$zem_contact_from = $email;
		}
    }
    }

	return zem_contact_text(array(
		'default'	=> $email,
		'isError'	=> $isError,
		'label'		=> $label,
		'max'		=> $max,
		'min'		=> $min,
		'name'		=> $name,
		'required'	=> $required,
		'break'		=> $break,
		'size'		=> $size       	// changed '' to $size
	));
}

function zem_contact_select($atts)
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'name'		=> '',		// added name
		'break'		=> '<br />',
		'delimiter'	=> ',',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('option'),
		'list'		=> zem_contact_gTxt('general_inquiry'),
		'required'	=> 'yes',
		'selected'	=> 'yes'
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	$list = array_map('trim', split($delimiter, $list));

	$value = ps($name) ? ps($name) : $selected;

	if (ps('zem_contact_submit') and $required == 'yes' and empty($value))
	{
		$zem_contact_error[] = zem_contact_gTxt('field_missing', $label);
		$isError = "errorElement";
	}

	elseif (ps($name) and !in_array($value, $list))
	{
		$zem_contact_error[] = zem_contact_gTxt('invalid_value', $label, $value);
		$isError = "errorElement";
	}

	elseif (ps($name))
	{
		$zem_contact_form[$label] = $value;
	}

	$out = '';

	foreach ($list as $item)
	{
		$item = htmlspecialchars($item);

		if ($item == $value)		// changed $selected to $value
		{
			$out .= n.t.'<option selected="1">'.$item.'</option>';
		}

		else
		{
			$out .= n.t.'<option>'.$item.'</option>';
		}
	}

	if ($required == 'yes')
	{
	return '<label for="'.$name.'" class="zemRequired'.$isError.' '.$name.'">'.$label.'</label>'.$break.
		n.'<select id="'.$name.'" name="'.$name.'">'.
			$out.
		n.'</select>';
	}
	else
	{
	return '<label for="'.$name.'" class="'.$name.'">'.$label.'</label>'.$break.
		n.'<select id="'.$name.'" name="'.$name.'">'.
			$out.
		n.'</select>';
	}
}

function zem_contact_checkbox($atts)
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'break'		=> ' ',
		'checked'	=> 'no',
		'isError'	=> '',
		'label'		=> zem_contact_gTxt('checkbox'),
		'name'		=> '',
		'required'	=> 'yes'
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	$value = ps('zem_contact_submit') ? (bool) ps($name) : '';

	if (ps('zem_contact_submit') and $required == 'yes' and empty($value))
	{
		$zem_contact_error[] = zem_contact_gTxt('field_missing', $label);
		$isError = "errorElement";
	}

	elseif (ps('zem_contact_submit'))
	{
		$zem_contact_form[$label] = ($value) ? gTxt('yes') : gTxt('no');
	}

	if ($required == 'yes')
	{
	return '<input type="checkbox" id="'.$name.'" class="zemRequired'.$isError.'" name="'.$name.'"'.
		( ( ($checked == 'yes') and $value) ? ' checked="checked" />' : ' />').$break.
		'<label for="'.$name.'" class="zemRequired'.$isError.' '.$name.'">'.$label.'</label>';
	}
	else
	{
	return '<input type="checkbox" id="'.$name.'" name="'.$name.'"'.
		( ( ($checked == 'yes') and $value) ? ' checked="checked" />' : ' />').$break.
		'<label for="'.$name.'" class="'.$name.'">'.$label.'</label>';
	}
}

function zem_contact_serverinfo($atts)
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'label'		=> '',
		'name'		=> ''
	), $atts));

	if (empty($name))
	{
		$name = strtolower(preg_replace('/\W/', '', $label));
	}

	if ($name and ps('zem_contact_submit'))
	{
		$zem_contact_form[$label] = serverSet($name);
	}
}

function zem_contact_secret($atts, $thing = '')
{
	global $zem_contact_form, $zem_contact_error;

	extract(lAtts(array(
		'name'		=> '',
		'value'		=> ''
	), $atts));

	if ($value)
	{
		$value = htmlspecialchars($value);
	}

	elseif ($thing)
	{
		$value = htmlspecialchars(trim(parse($thing)));
	}

	if (ps($name))
	{
		$zem_contact_form[$label] = $value;
	}

	return '<input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$value.'" />';
}

function zem_contact_send_article($atts) {

	if (!isset($_REQUEST['zem_contact_send_article'])) {
		$linktext = (empty($atts['linktext'])) ? 'send article' : $atts['linktext'];
		$join = (empty($_SERVER['QUERY_STRING'])) ? '?' : '&amp;';
		$href = $_SERVER['REQUEST_URI'].$join.'zem_contact_send_article=yes';
		return '<a href="'.$href.'">'.$linktext.'</a>';
	}
	return;

}

function zem_contact_submit($atts)
{
	global $zem_contact_nonce, $zem_contact_error;

	extract(lAtts(array(
		'label'		=> zem_contact_gTxt('send')
	), $atts));

	return '<input type="submit" id="zemSubmit" name="zem_contact_submit" value="'.$label.'" />';
}

class zemcontact_evaluation {

	var $status;

	function zemcontact_evaluation() {
		$this->status = 0;
	}

	function add_zemcontact_status($check) {
		$this->status = $check;
	}

	function get_zemcontact_status() {
		return $this->status;
	}

}

function &get_zemcontact_evaluator() {

	static $instance;

	// If the instance is not there, create one
	if(!isset($instance)) {
		$instance = new zemcontact_evaluation();
	}
	return $instance;

}
