/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */

/**
 * @param {string=} sEmail
 * @param {string=} sName
 *
 * @constructor
 */
function EmailModel(sEmail, sName)
{
	this.email = sEmail || '';
	this.name = sName || '';
	this.privateType = null;

	this.clearDuplicateName();
}

/**
 * @static
 * @param {AjaxJsonEmail} oJsonEmail
 * @return {?EmailModel}
 */
EmailModel.newInstanceFromJson = function (oJsonEmail)
{
	var oEmailModel = new EmailModel();
	return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
};

/**
 * @type {string}
 */
EmailModel.prototype.name = '';

/**
 * @type {string}
 */
EmailModel.prototype.email = '';

/**
 * @type {(number|null)}
 */
EmailModel.prototype.privateType = null;

EmailModel.prototype.clear = function ()
{
	this.email = '';
	this.name = '';
	this.privateType = null;
};

/**
 * @returns {boolean}
 */
EmailModel.prototype.validate = function ()
{
	return '' !== this.name || '' !== this.email;
};

/**
 * @param {boolean} bWithoutName = false
 * @return {string}
 */
EmailModel.prototype.hash = function (bWithoutName)
{
	return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#';
};

EmailModel.prototype.clearDuplicateName = function ()
{
	if (this.name === this.email)
	{
		this.name = '';
	}
};

/**
 * @return {number}
 */
EmailModel.prototype.type = function ()
{
	if (null === this.privateType)
	{
		if (this.email && '@facebook.com' === this.email.substr(-13))
		{
			this.privateType = Enums.EmailType.Facebook;
		}

		if (null === this.privateType)
		{
			this.privateType = Enums.EmailType.Default;
		}
	}
	
	return this.privateType;
};

/**
 * @param {string} sQuery
 * @return {boolean}
 */
EmailModel.prototype.search = function (sQuery)
{
	return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase());
};

/**
 * @param {string} sString
 */
EmailModel.prototype.parse = function (sString)
{
	this.clear();

	sString = Utils.trim(sString);

	var
		mRegex = /(?:"([^"]+)")? ?<?(.*?@[^>,]+)>?,? ?/g,
		mMatch = mRegex.exec(sString)
	;

	if (mMatch)
	{
		this.name = mMatch[1] || '';
		this.email = mMatch[2] || '';

		this.clearDuplicateName();
	}
	else if ((/^[^@]+@[^@]+$/).test(sString))
	{
		this.name = '';
		this.email = sString;
	}
};

/**
 * @param {AjaxJsonEmail} oJsonEmail
 * @return {boolean}
 */
EmailModel.prototype.initByJson = function (oJsonEmail)
{
	var bResult = false;
	if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object'])
	{
		this.name = Utils.trim(oJsonEmail.Name);
		this.email = Utils.trim(oJsonEmail.Email);

		bResult = '' !== this.email;
		this.clearDuplicateName();
	}

	return bResult;
};

/**
 * @param {boolean} bFriendlyView
 * @param {boolean=} bWrapWithLink = false
 * @param {boolean=} bEncodeHtml = false
 * @return {string}
 */
EmailModel.prototype.toLine = function (bFriendlyView, bWrapWithLink, bEncodeHtml)
{
	var sResult = '';
	if ('' !== this.email)
	{
		bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink;
		bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml;
		
		if (bFriendlyView && '' !== this.name)
		{
			sResult = bWrapWithLink ? '<a href="mailto:' + Utils.encodeHtml('"' + this.name + '" <' + this.email + '>') +
				'" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '</a>' : 
					(bEncodeHtml ? Utils.encodeHtml(this.name) : this.name);
		}
		else
		{
			sResult = this.email;
			if ('' !== this.name)
			{
				if (bWrapWithLink)
				{
					sResult = Utils.encodeHtml('"' + this.name + '" <') +
						'<a href="mailto:' + Utils.encodeHtml('"' + this.name + '" <' + this.email + '>') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(sResult) + '</a>' + Utils.encodeHtml('>');
				}
				else
				{
					sResult = '"' + this.name + '" <' + sResult + '>';
					if (bEncodeHtml)
					{
						sResult = Utils.encodeHtml(sResult);
					}
				}
			}
			else if (bWrapWithLink)
			{
				sResult = '<a href="mailto:' + Utils.encodeHtml(this.email) + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.email) + '</a>';
			}
		}
	}

	return sResult;
};

/**
 * @param {string} $sEmailAddress
 * @return {boolean}
 */
EmailModel.prototype.mailsoParse = function ($sEmailAddress)
{
	$sEmailAddress = Utils.trim($sEmailAddress);
	if ('' === $sEmailAddress)
	{
		return false;
	}

	var
		substr = function (str, start, len) {
			str += '';
			var	end = str.length;

			if (start < 0) {
				start += end;
			}
			
			end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
			
			return start >= str.length || start < 0 || start > end ? false : str.slice(start, end);
		},
				
		substr_replace = function (str, replace, start, length) {
			if (start < 0) {
				start = start + str.length;
			}
			length = length !== undefined ? length : str.length;
			if (length < 0) {
				length = length + str.length - start;
			}
			return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
		},
		
		$sName = '',
		$sEmail = '',
		$sComment = '',

		$bInName = false,
		$bInAddress = false,
		$bInComment = false,

		$aRegs = null,

		$iStartIndex = 0,
		$iEndIndex = 0,
		$iCurrentIndex = 0
	;

	while ($iCurrentIndex < $sEmailAddress.length)
	{
		switch ($sEmailAddress.substr($iCurrentIndex, 1))
		{
			case '"':
				if ((!$bInName) && (!$bInAddress) && (!$bInComment))
				{
					$bInName = true;
					$iStartIndex = $iCurrentIndex;
				}
				else if ((!$bInAddress) && (!$bInComment))
				{
					$iEndIndex = $iCurrentIndex;
					$sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
					$sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
					$iEndIndex = 0;
					$iCurrentIndex = 0;
					$iStartIndex = 0;
					$bInName = false;
				}
				break;
			case '<':
				if ((!$bInName) && (!$bInAddress) && (!$bInComment))
				{
					if ($iCurrentIndex > 0 && $sName.length === 0)
					{
						$sName = substr($sEmailAddress, 0, $iCurrentIndex);
					}

					$bInAddress = true;
					$iStartIndex = $iCurrentIndex;
				}
				break;
			case '>':
				if ($bInAddress)
				{
					$iEndIndex = $iCurrentIndex;
					$sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
					$sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
					$iEndIndex = 0;
					$iCurrentIndex = 0;
					$iStartIndex = 0;
					$bInAddress = false;
				}
				break;
			case '(':
				if ((!$bInName) && (!$bInAddress) && (!$bInComment))
				{
					$bInComment = true;
					$iStartIndex = $iCurrentIndex;
				}
				break;
			case ')':
				if ($bInComment)
				{
					$iEndIndex = $iCurrentIndex;
					$sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
					$sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
					$iEndIndex = 0;
					$iCurrentIndex = 0;
					$iStartIndex = 0;
					$bInComment = false;
				}
				break;
			case '\\':
				$iCurrentIndex++;
				break;
		}

		$iCurrentIndex++;
	}

	if ($sEmail.length === 0)
	{
		$aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
		if ($aRegs && $aRegs[0])
		{
			$sEmail = $aRegs[0];
		}
		else
		{
			$sName = $sEmailAddress;
		}
	}

	if ($sEmail.length > 0 && $sName.length === 0 && $sComment.length === 0)
	{
		$sName = $sEmailAddress.replace($sEmail, '');
	}

	$sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
	$sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
	$sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');

	// Remove backslash
	$sName = $sName.replace(/\\\\(.)/, '$1');
	$sComment = $sComment.replace(/\\\\(.)/, '$1');

	this.name = $sName;
	this.email = $sEmail;

	this.clearDuplicateName();
	return true;
};

/**
 * @return {string}
 */
EmailModel.prototype.inputoTagLine = function ()
{
	return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email;
};
