using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.SharpZipLib.Zip;

namespace WolvenKit.App
{
    public class WKPackage
    {
        private XDocument Assembly;
        private string Icon;

        public string RootFolder;

        /// <summary>
        /// Collects the info and the files from an already created WolveKit package.
        /// </summary>
        /// <param name="Path"></param>
        public WKPackage(string Path)
        {
            //TODO: Finish this once we crate the installer or whatever.
        }

        /// <summary>
        /// Creates a WolveKit package.
        /// </summary>
        /// <param name="assmebly">The details of the mod. Generate this with CreateModAssembly();</param>
        /// <param name="icon">The icon of the mod.</param>
        /// <param name="RootFolder">The root folder of the mod.</param>
        public WKPackage(XDocument assmebly, string icon, string rootfolder)
        {
            Assembly = assmebly;
            Icon = icon;
            RootFolder = rootfolder;
        }

        /// <summary>
        /// Saves the package to the specified output path.
        /// </summary>
        /// <param name="OutputPath">The path to save the file to.</param>
        public void Save(string OutputPath)
        {
            if (Icon != null && Assembly != null)
            {
                FileStream fsOut = File.Create(OutputPath);
                ZipOutputStream zipStream = new ZipOutputStream(fsOut);
                int folderOffset = RootFolder.Length + (RootFolder.EndsWith("\\") ? 0 : 1);
                Commonfunctions.CompressFolder(RootFolder, zipStream, folderOffset);
                Commonfunctions.CompressFile(Icon, zipStream, "Icon" + Path.GetExtension(Icon));
                Commonfunctions.CompressStream(Commonfunctions.XDocToByteArray(Assembly), "Assembly.xml", zipStream);
                zipStream.IsStreamOwner = true;
                zipStream.Close();
            }
            else
            {
                throw new Exception("Missing parameters!");
            }
        }

        /// <summary>
        /// This creates the modassembly xml. Values which are optional are marked in their description as such. If a value is not given pass the method NULL for that value.
        /// </summary>
        /// <param name="version">The Version of the mod. [REQUIRED]</param>
        /// <param name="name">The name of the mod. [REQUIRED]</param>
        /// <param name="Author">Author info [Name,NexusmodsProfile,Web,Facebook,Twitter,Youtube] Note: Only Name is required!</param>
        /// <param name="description">The description of the mod. [OPTIONAL]</param>
        /// <param name="Largedescription">Aditional description of the mod. [OPTIONAL]</param>
        /// <param name="license">The License of the mod. [OPTIONAL]</param>
        /// <param name="Colors">Header background color, If true the header text will be black otherwise white, Icon bacground color. [REQUIRED]</param>
        /// /// <param name="Contents">The commands to run on the games files. eg.: adding new lines to xmls and such. [OPTIONAL]</param>
        /// <returns></returns>
        public static XDocument CreateModAssembly(
            string version,
            string name,
            Tuple<string,string,string,string,string,string> Author,
            string description,
            string Largedescription,
            string license,
            Tuple<Color,bool,
            Color> Colors,
            List<XElement> Contents)
        {
            if (version == null || name == null || Author.Item1 == null || Colors == null)
            {
                throw new ArgumentException("Invalid parameters when trying to generate the assembly.xml!");
            }
            var rootnode = new XElement("package",new XAttribute("version",version), new XAttribute("name",name));
            var authorelement = new XElement("author",new XElement("displayName",Author.Item1));
            var metadataelement = new XElement("metadata");
            if (Author.Item2 != null || Author.Item2 != "")
                authorelement.Add(new XElement("actionLink",Author.Item2));
            if (Author.Item3 != null || Author.Item3 != "")
                authorelement.Add(new XElement("web", Author.Item3));
            if (Author.Item4 != null || Author.Item4 != "")
                authorelement.Add(new XElement("facebook", Author.Item4));
            if (Author.Item5 != null || Author.Item5 != "")
                authorelement.Add(new XElement("twitter", Author.Item5));
            if (Author.Item6 != null || Author.Item6 != "")
                authorelement.Add(new XElement("youtube", Author.Item6));
            metadataelement.Add(authorelement);
            if(description?.Length > 0)
                metadataelement.Add(new XElement("description",description));
            if (Largedescription?.Length > 0)
                metadataelement.Add(new XElement("largeDescription", Largedescription));
            if (license?.Length > 0)
                metadataelement.Add(new XElement("license", license));
            rootnode.Add(metadataelement);
            rootnode.Add(new XElement("colors",new XElement("headerBackground", ColorTranslator.ToHtml(Colors.Item1),new XAttribute("useBlackTextColor",Colors.Item2)),new XElement("iconBackground",ColorTranslator.ToHtml(Colors.Item3))));
            rootnode.Add(new XElement("content", Contents));
            return new XDocument(new XDeclaration("1.0", "UTF-8", "True"),rootnode);
        }
    }
}
