var RcptMailAddr = 1;
var RcptMailGroup = 2;
var RcptOrgz = 3;

// 메일 수신자 정보 저장 클래스
function Recipient(name, type, value)
{
    this.name = name;
    this.type = type;       // RcptMailAddr, RcptMailGroup, or RcptOrgz
    this.value = value;
    this.exist = false;   
}

// 메일 수신자 목록 저장 클래스
function Recipients()
{
    this.recipients = [];
    
    // 수신자 추가
    this.Add = function (recipient, allowdup)
    {
        if (recipient == null) return false;
        var retval = false;
        if (allowdup)
        {
            this.recipients.push(recipient);
            recipient.exist = true;
            retval = true;
        }
        else
        {
            var r;
            if (recipient.type == RcptMailAddr)
            {
                r = this.FindByValue(recipient.value);
                if (r == null) { this.recipients.push(recipient); recipient.exist = true; retval = true; }
                else { r.name = recipient.name; r.exist = true; }
            }
            else
            {
                r = this.FindByNameTypeValue(recipient.name, recipient.type, recipient.value);
                if (r == null) { this.recipients.push(recipient); recipient.exist = true; retval = true; }
                else { r.name = recipient.name; r.exist = true; }
            }
        }
        return retval;
    }

    this.AddRecipients = function (rcpts) {
        for (var i = 0; i < rcpts.recipients.length; i++) {
            this.Add(rcpts.recipients[i], false);
        }
    }
    
    // 수신자(메일 주소) 추가
    this.AddMailAddress = function(name, email) {
        name = name.trim();
        if (name.length == 0) name = email;
        this.Add(new Recipient(name, RcptMailAddr, email), false);
    }

    // 수신자(이름 + 메일 주소) 추가
    this.AddMailAddressEx = function (fullName) {
        var name, value;
        var re = /(\x22([^\x22]*)\x22)?(\s*)[<\x28]?([-+.'!#$%&=/\w\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+@\w+([-.]\w+)*\.\w+([-.]\w+)*)[>\x29]?/gi;
        var m;
        while ((m = re.exec(fullName)) !== null) {
            name = m[2]; if (name === undefined) name = "";
            value = m[4];
            //console.log(name + "," + value);
            if (this.FindByValue(value) == null) this.AddMailAddress(name, value);
        }
    }
    
    // 수신자(그룹) 추가
    this.AddMailGroup = function(name, guid)
    {
        this.Add(new Recipient(name, RcptMailGroup, guid), false);
    }
    
    // 수신자(조직도) 추가
    this.AddOrgz = function(name, guid)
    {
        this.Add(new Recipient(name, RcptOrgz, guid), false);
    }    
    
    // 수신자 삭제
    this.Remove = function(name, value)
    {
        for (var i = this.recipients.length - 1; i >= 0; i--)
        {
            if (this.recipients[i].name == name && this.recipients[i].value == value) this.recipients.splice(i, 1);
        }
    }

    // 수신자 삭제
    this.RemoveByIndex = function (index) {
        this.recipients.splice(index, 1);
    }

    // 수신자 입력 문자열(메일 주소 문자열)로 부터 수신자 목록 갱신
    /*
    this.AddFromString = function(str)
    {
        for (var i = 0; i < this.recipients.length; i++) this.recipients[i].exist = false;        

        var name, value, r;
        var re = /(\x22[^\x22]*\x22)?(\s*)[<\x28]?(\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)[>\x29]?/gi;
        var m;
        while ((m = re.exec(str)) != null)
        {
            name = m[0];            
            value = m[3];
            r = this.FindByValue(value);            
            if (r == null)
            {
                r = new Recipient(name, RcptMailAddr, value); r.exist = true;
                this.Add(r, false);
            }
            else
            {
                r.name = name; r.exist = true;
            }            
        }
        
        re = /@(\x5b([^\x5d]*)\x5d)/gi;
        while ((m = re.exec(str)) != null)
        {
            var name = m[0];
            r = this.FindByNameType(name, RcptMailGroup);
            if (r != null) r.exist = true;
            else alert(name + '은 명확하지 않은 수신자 그룹이므로 추가될 수 없습니다.');
        }
        
        re = /#(\x5b([^\x5d]*)\x5d)/gi;
        while ((m = re.exec(str)) != null)
        {
            var name = m[0];
            r = this.FindByNameType(name, RcptOrgz);
            if (r != null) r.exist = true;
            else alert(name + '은 명확하지 않은 조직도 항목이므로 추가될 수 없습니다.');
        }
        
        for (var i = 0; i < this.recipients.length; i++) 
            if (this.recipients[i].exist == false)
            {
                alert(this.recipients[i].name + '은 부정확한 수신자이므로 삭제됩니다.');
                this.recipients.remove(i);
                i = -1;
            }
    }
    */
    
    // 수신자 목록을 수신자 입력 문자열로 변환해서 반환
//    this.ToString = function()
//    {
//        var str = '';
//        for (var i = 0; i < this.recipients.length; i++)
//        {
//            if (i > 0) str += ';';
//            str += this.recipients[i].name;
//        }
//        return str;
//    }
    
    this.FindByValue = function(value)
    {
        for (var i = 0; i < this.recipients.length; i++)
        {
            if (this.recipients[i].value == value) return this.recipients[i];
        }
        return null;
    }

    this.FindByNameType = function(name, type)
    {
        for (var i = 0; i < this.recipients.length; i++)
        {
            if (this.recipients[i].name == name && this.recipients[i].type == type) return this.recipients[i];
        }
        return null;
    }

    // 동일 이름을 갖는 팀을 추가할 수 있도록 value까지 검사
    this.FindByNameTypeValue = function (name, type, value)
    {
        for (var i = 0; i < this.recipients.length; i++)
        {
            if (this.recipients[i].name == name && this.recipients[i].type == type && this.recipients[i].value == value) return this.recipients[i];
        }
        return null;
    }
    
    // 수신자 목록을 HTTP 파라미터로 변환해서 반환
    // "name" (mail address);@[name] (guid); #[name] (guid);
//    this.GetHttpRequestParam = function()
//    {
//        var param = '';
//        for (var i = 0; i < this.recipients.length; i++)
//        {
//            var r = this.recipients[i];
//            if (r.type == RcptMailAddr) param += r.name + ';';
//            else if (r.type == RcptMailGroup) param += r.name + '(' + r.value + ');';
//            else param += r.name + '(' + r.value + ');';
//        }
//        return param;
//    }

    this.Length = function () {
        return this.recipients.length;
    }
    
    this.DebugPrint = function()
    {
        for (var i = 0; i < this.recipients.length; i++)
        {
            var r = this.recipients[i];
            if (r.type == RcptMailAddr) alert('메일 주소:' + r.name + ',' + r.value);
            else if (r.type == RcptMailGroup) alert('메일 그룹:' + r.name + ',' + r.value);
            else alert('조직도:' + r.name + ',' + r.value);
        }
    }
}

// Recipients 인스턴스를 JSON 문자열로 변환
Recipients.ToJsonString = function(rcpts)
{
    if (rcpts == null) return '';
    else return JSON.stringify(rcpts.recipients);
}

// JSON 문자열에서 Recipients 인스턴스로 변환
Recipients.FromJsonString = function(str)
{
    var arr = JSON.parse(str);
    var rcpts = new Recipients();
    for (var i = 0; i < arr.length; i++)
    {
        var rcpt = new Recipient(arr[i].name, arr[i].type, arr[i].value);
        rcpts.Add(rcpt, true);
    }
    return rcpts;
}
