using System;
using System.Collections.Generic;
using System.Xml;
using Orienteering.Standard;

namespace Orienteering.Competition {
    public class Result {
        internal Orienteering.Data.Result data;

        public Result() {
            data = new Orienteering.Data.Result();
        }

        public Result(Category category, Runner runner, DataBase dataBase) {
            data = new Orienteering.Data.Result();
            if (category != null)
                Category = category;
            Runner = runner;
            ResultType = ResultType.None;
            Save(dataBase);
        }

        public Result(Orienteering.Data.Result _data) {
            data = _data;
        }

        public Runner Runner {
            get { return new Runner(data.Runner); }
            set { data.Runner = value.data; }
        }

        public Category Category {
            get { return new Category(data.Category); }
            set { data.Category = value.data; }
        }

        public DateTime Start {
            get { return data.Start; }
            set { data.Start = value; }
        }

        public DateTime Finish {
            get { return data.Finish; }
            set { data.Finish = value; }
        }

        public ResultType ResultType {
            get { return data.ResultType; }
            set { data.ResultType = value; }
        }

        public Result(XmlNode xml, Runner runner, DataBase dataBase) {
            data = new Orienteering.Data.Result();
            Stage stage = null;
            foreach (XmlAttribute xmlattr in xml.Attributes) {
                if (xmlattr.Name == "start")
                    Start = Convert.ToDateTime(xmlattr.Value);
                if (xmlattr.Name == "finish")
                    Finish = Convert.ToDateTime(xmlattr.Value);
                if (xmlattr.Name == "stage")
                    stage = runner.Club.Competition.Stage(Convert.ToInt32(xmlattr.Value), dataBase);
                if (xmlattr.Name == "resultType") {
                    switch (xmlattr.Value) {
                        case "Disq" : ResultType = ResultType.Disq;
                            break;
                        case "None" : ResultType = ResultType.None;
                            break;
                        case "Ok" : ResultType = ResultType.Ok;
                            break;
                    }
                }
            }
            Runner = runner;

            foreach (XmlAttribute xmlattr in xml.Attributes)
                if (xmlattr.Name == "category")
                    Category = stage.Category(xmlattr.Value, dataBase);
            Save(dataBase);
        }

        public XmlNode Xml(XmlDocument xml) {
            XmlNode res = xml.CreateNode("element", "result", "");

            XmlAttribute categoryAttr = (XmlAttribute)xml.CreateNode("attribute", "category", "");
            categoryAttr.Value = Category.Name;
            res.Attributes.Append(categoryAttr);

            XmlAttribute stageAttr = (XmlAttribute)xml.CreateNode("attribute", "stage", "");
            stageAttr.Value = Category.Course.Stage.Number.ToString();
            res.Attributes.Append(stageAttr);

            XmlAttribute startAttr = (XmlAttribute)xml.CreateNode("attribute", "start", "");
            startAttr.Value = Convert.ToString(Start);
            res.Attributes.Append(startAttr);

            XmlAttribute finishAttr = (XmlAttribute)xml.CreateNode("attribute", "finish", "");
            finishAttr.Value = Convert.ToString(Finish);
            res.Attributes.Append(finishAttr);

            XmlAttribute resultTypeAttr = (XmlAttribute)xml.CreateNode("attribute", "resultType", "");
            resultTypeAttr.Value = Convert.ToString(ResultType);
            res.Attributes.Append(resultTypeAttr);

            return res;
        }

        public XmlNode StartTime(XmlDocument xml, int rank) {
            XmlNode res = xml.CreateNode("element", "tr", "");

            XmlNode rankNode = (XmlNode)xml.CreateNode("element", "td", "");
            rankNode.InnerText = rank.ToString()+".";
            res.AppendChild(rankNode);

            XmlNode nameNode = (XmlNode)xml.CreateNode("element", "td", "");
            nameNode.InnerText = Runner.Name;
            res.AppendChild(nameNode);

            XmlNode timeNode = (XmlNode)xml.CreateNode("element", "td", "");
            timeNode.InnerText = (Start-Category.Course.Stage.StartTime).ToString();
            res.AppendChild(timeNode);

            return res;
        }

        public XmlNode ResultXml(XmlDocument xml, int rank) {
            XmlNode res = xml.CreateNode("element", "tr", "");

            XmlNode rankNode = (XmlNode)xml.CreateNode("element", "td", "");
            if (rank > 0)
                rankNode.InnerText = rank.ToString()+".";
            else
                rankNode.InnerText = "";
            res.AppendChild(rankNode);

            XmlNode nameNode = (XmlNode)xml.CreateNode("element", "td", "");
            nameNode.InnerText = Runner.Name;
            res.AppendChild(nameNode);

            XmlNode timeNode = (XmlNode)xml.CreateNode("element", "td", "");
            if (ResultType == ResultType.Ok)
                timeNode.InnerText = (Finish-Start).ToString();
            else if (ResultType == ResultType.Disq)
                timeNode.InnerText = "DISQ";
            res.AppendChild(timeNode);

            return res;
        }

        public void Save(DataBase dataBase) {
            data.Save(dataBase.data);
        }
    }
}
