using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Collections;
using System.Collections.Generic;

public class RcptItem
{
    public string Type;     // to, cc, bcc
    public string Name;     // Help
    public string Value;    // help@tabslab.com
    public string Source;   // email, contact, orgz

    public RcptItem(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public RcptItem(string type, string name, string value, string source)
    {
        Type = type;
        Name = name;
        Value = value;
        Source = source;
    }
}

public class AdditionItem
{
    public string Name;
    public string Value;

    public AdditionItem(string name, string value)
    {
        Name = name;
        Value = value;
    }
}

public class SrcMsgItem
{
    public string MsgId;
    public string Action;
    public SrcMsgItem(string msgId, string action)
    {
        MsgId = msgId;
        Action = action;
    }
}

/// <summary>
/// 메시지 확장 정보를 기록하기 위한 클래스입니다.
/// </summary>
/// <example>
/// <etcConfig>
///    <recipient>
///        <item>
///            <type>to</type>
///            <name>TABS TechSupport</name>
///            <value>help@tabslab.com</value>
///            <source>email</source>
///        </item>
///        <item>
///            <type>cc</type>
///            <name>TABS Sales</name>
///            <value>sales@tabslab.com</value>
///            <source>contact</source>
///        </item>
///    </recipient>
///    <addition>
///        <item>
///            <name>SaveToSent</name>
///            <value>true</value>
///        </item>
///        <item>
///            <name>ReadRequest</name>
///            <value>false</value>
///        </item>
///    </addition>
///    <srcMsg>
///        <item>
///            <msgId>52592c36-3abf-4597-94fe-3260bcd49b2f</msgId>
///            <action>forward</action>
///        </item>
///    </srcMsg>
/// </etcConfig>
/// </example>
public class MsgExtender
{
    private XmlDocument _doc;
    private List<RcptItem> _rcptItems;
    private List<AdditionItem> _additionItems;
    private List<SrcMsgItem> _srcMsgItems;

    public MsgExtender()
    {
        _doc = new XmlDocument();
        _rcptItems = new List<RcptItem>();
        _additionItems = new List<AdditionItem>();
        _srcMsgItems = new List<SrcMsgItem>();
    }

    public List<RcptItem> RcptItems
    {
        get { return _rcptItems; }
        set { _rcptItems = value; }
    }

    public bool HasValue
    {
        get
        {
            if (_rcptItems != null &&
                _rcptItems.Count > 0) return true;
            if (_additionItems != null &&
                _additionItems.Count > 0) return true;

            return false;
        }
    }

    public List<AdditionItem> AdditionItems
    {
        get { return _additionItems; }
        set { _additionItems = value; }
    }

    public string GetAddtionItemValue(string name)
    {
        AdditionItem findItem = _additionItems.Find(delegate(AdditionItem item) { return item.Name == name; });
        return (findItem != null) ? findItem.Value : "";
    }

    public List<SrcMsgItem> SrcMsgItems
    {
        get { return _srcMsgItems; }
        set { _srcMsgItems = value; }
    }

    private XmlNode GetNode(XmlNodeList list, string name)
    {
        foreach (XmlNode node in list)
        {
            if (node.Name == name)
                return node;
        }
        return null;
    }

    public void LoadFromXml(string xml)
    {
        _doc.LoadXml(xml);
        XmlNode etcConfig = GetNode(_doc.ChildNodes, "etcConfig");
        GetRecipientItem(ref etcConfig);
        GetAdditionItem(ref etcConfig);
        GetSrcMsgItem(ref etcConfig);
    }

    public string MakeXml()
    {
        XmlElement etcConfig = _doc.CreateElement("etcConfig");
        _doc.AppendChild(etcConfig);

        if (RcptItems.Count > 0) MakeRecipientItem();
        if (AdditionItems.Count > 0) MakeAdditionItem();
        if (SrcMsgItems.Count > 0) MakeSrcMsgItem();

        return _doc.InnerXml;
    }

    private void GetAdditionItem(ref  XmlNode etcConfig)
    {
        XmlNode addition = GetNode(etcConfig.ChildNodes, "addition");

        if (addition != null)
        {
            foreach (XmlNode node in addition.ChildNodes)
            {
                if (node.Name == "item")
                {
                    XmlNode name = GetNode(node.ChildNodes, "name");
                    XmlNode value = GetNode(node.ChildNodes, "value");

                    AdditionItems.Add(new AdditionItem(name.InnerText, value.InnerText));
                }
            }
        }
    }

    private void GetRecipientItem(ref XmlNode etcConfig)
    {
        XmlNode recipient = GetNode(etcConfig.ChildNodes, "recipient");

        if (recipient != null)
        {
            foreach (XmlNode node in recipient.ChildNodes)
            {
                if (node.Name == "item")
                {
                    XmlNode type = GetNode(node.ChildNodes, "type");
                    XmlNode name = GetNode(node.ChildNodes, "name");
                    XmlNode value = GetNode(node.ChildNodes, "value");
                    XmlNode source = GetNode(node.ChildNodes, "source");

                    RcptItems.Add(new RcptItem(type.InnerText, name.InnerText, value.InnerText, source.InnerText));
                }
            }
        }
    }

    private void GetSrcMsgItem(ref XmlNode etcConfig)
    {
        XmlNode srcMsg = GetNode(etcConfig.ChildNodes, "srcMsg");

        if (srcMsg != null)
        {
            foreach (XmlNode node in srcMsg.ChildNodes)
            {
                if (node.Name == "item")
                {
                    XmlNode msgId = GetNode(node.ChildNodes, "msgId");
                    XmlNode action = GetNode(node.ChildNodes, "action");

                    SrcMsgItems.Add(new SrcMsgItem(msgId.InnerText, action.InnerText));
                }
            }
        }
    }

    private void MakeRecipientItem()
    {
        XmlElement recipient = _doc.CreateElement("recipient");
        XmlElement item, type, name, value, source;

        foreach (RcptItem Item in this.RcptItems)
        {
            item = _doc.CreateElement("item");

            type = _doc.CreateElement("type");
            name = _doc.CreateElement("name");
            value = _doc.CreateElement("value");
            source = _doc.CreateElement("source");

            type.InnerText = Item.Type;
            name.InnerText = Item.Name;
            value.InnerText = Item.Value;
            source.InnerText = Item.Source;

            item.AppendChild(type);
            item.AppendChild(name);
            item.AppendChild(value);
            item.AppendChild(source);

            recipient.AppendChild(item);
            _doc.DocumentElement.AppendChild(recipient);
        }
    }

    private void MakeAdditionItem()
    {
        XmlElement addition = _doc.CreateElement("addition");
        XmlElement item, name, value;

        foreach (AdditionItem Item in this.AdditionItems)
        {
            item = _doc.CreateElement("item");

            name = _doc.CreateElement("name");
            value = _doc.CreateElement("value");

            name.InnerText = Item.Name;
            value.InnerText = Item.Value;

            item.AppendChild(name);
            item.AppendChild(value);

            addition.AppendChild(item);
            _doc.DocumentElement.AppendChild(addition);
        }
    }

    private void MakeSrcMsgItem()
    {
        XmlElement srcMsg = _doc.CreateElement("srcMsg");
        XmlElement item, msgId, action;

        foreach (SrcMsgItem Item in this.SrcMsgItems)
        {
            item = _doc.CreateElement("item");

            msgId = _doc.CreateElement("msgId");
            action = _doc.CreateElement("action");

            msgId.InnerText = Item.MsgId;
            action.InnerText = Item.Action;

            item.AppendChild(msgId);
            item.AppendChild(action);

            srcMsg.AppendChild(item);
            _doc.DocumentElement.AppendChild(srcMsg);
        }
    }

    public override string ToString()
    {
        return _doc.InnerXml;
    }
}