using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.IO;
using System.Xml.Linq;

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace KsiegaGosci_MVC.Models
{
    //klasa encji
    public struct Wpis
    {
        private string nazwaUżytkownika;
        private string treść;
        private DateTime data;
        private string adresIP;

        [Required(ErrorMessage="Wymagane jest wpisanie nazwy użytkownika")]
        [StringLength(256,MinimumLength=1,ErrorMessage="Niepoprawna długość nazwy użytkownika")]
        [RegularExpression(@"[a-zA-Z0-9'.ąćęłńóśżźĄĆĘŁŃÓŚŻŹ\s]{1,256}", ErrorMessage="Nazwa użytkownika zawiera niepoprawne znaki")]
        [DisplayName("Nazwa użytkownika")]
        public string NazwaUżytkownika { get { return nazwaUżytkownika; } }

        [RegularExpression(@"[a-zA-Z0-9'.ąćęłńóśżźĄĆĘŁŃÓŚŻŹ\s]{1,16384}", ErrorMessage = "Treść wpisu zawiera niepoprawne znaki")]
        public string Treść { get { return treść; } }

        [Required] public DateTime Data { get { return data; } }
        [Required] public string AdresIP { get { return adresIP; } }

        public Wpis(string nazwaUżytkownika, string treść, DateTime data, string adresIP)
        {
            this.nazwaUżytkownika = nazwaUżytkownika;
            this.treść = treść;
            this.data = data;
            this.adresIP = adresIP;
        }
    }

    //model
    public class Wpisy
    {
        List<Wpis> wpisy = new List<Wpis>();

        public bool ZapiszDoPlikuPoKażdymDodaniuWpisu = true;

        public void Dodaj(Wpis nowyWpis)
        {
            wpisy.Add(nowyWpis);
            if (ZapiszDoPlikuPoKażdymDodaniuWpisu) ZapiszDoPlikuXml();
        }

        public int Liczba
        {
            get
            {
                return wpisy.Count;
            }
        }

        public Wpis this[int i]
        {
            get
            {
                return wpisy[i];
            }
        }

        private static bool ZapiszDoPlikuXml(string nazwaPliku, List<Wpis> wpisy)
        {
            if (nazwaPliku == null || nazwaPliku == "") return false;

            try
            {
                if (File.Exists(nazwaPliku)) File.Copy(nazwaPliku, nazwaPliku + ".bak", true);

                XDocument xml = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("Wpisy",
                        new XElement("DataZapisu", DateTime.Now.ToString()),
                        from wpis in wpisy
                        select new XElement("Wpis",
                            new XElement("NazwaUżytkownika", wpis.NazwaUżytkownika),
                            new XElement("Treść", wpis.Treść),
                            new XElement("Data", wpis.Data),
                            new XElement("AdresIP", wpis.AdresIP)
                            )
                        )
                );

                xml.Save(nazwaPliku);
                return true;
            }
            catch (IOException exc)
            {
                MvcApplication.DopiszDoRejestruZdarzeń("Błąd we Wpisy.ZapiszDoPlikuXml: " + exc.Message); 
                return false;
            }
        }

        private static bool CzytajZPlikuXml(string nazwaPliku, List<Wpis> wpisy)
        {
            try
            {
                XDocument xml = XDocument.Load(nazwaPliku);

                var odczytaneWpisy = from wpis in xml.Descendants("Wpis")
                                     select
                                        new Wpis(
                                            wpis.Element("NazwaUżytkownika").Value,
                                            wpis.Element("Treść").Value,
                                            DateTime.Parse(wpis.Element("Data").Value),
                                            wpis.Element("AdresIP").Value);

                wpisy.Clear();
                wpisy.AddRange(odczytaneWpisy);

                return true;
            }
            catch (IOException exc)
            {
                MvcApplication.DopiszDoRejestruZdarzeń("Błąd we Wpisy.CzytajZPlikuXml: " + exc.Message); 
                return false;
            }
        }

        private string nazwaPlikuXml;

        private bool ZapiszDoPlikuXml()
        {
            return ZapiszDoPlikuXml(nazwaPlikuXml, wpisy);
        }

        private bool CzytajZPlikuXml()
        {
            return CzytajZPlikuXml(nazwaPlikuXml, wpisy);
        }

        public Wpisy(string nazwaPliku)
        {
            this.nazwaPlikuXml = nazwaPliku;
            CzytajZPlikuXml();
        }
    }
}