using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using CzokoŚmieciarka.MonoGameView.DataModels.Enums;
using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models;
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces;
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces.TrashCans;
using CzokoŚmieciarka.MonoGameView.DataModels.Models;
using MonoGameView.DataModels.Models;

namespace MonoGameView.DataModels
{
    public class MapLoader
    {
        public void Load(out int size, out IDrawables[,] grid, string filename)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(filename);
            XmlNode node = xml.GetElementsByTagName("Map").Item(0);
            XmlNode sizeNode = node.SelectSingleNode("/Map/Size");
            size = Convert.ToInt32(sizeNode.InnerText);
            grid = new IDrawables[size,size];
            for (int x = 0; x < size; x++)
            {
                for (int y = 0; y < size; y++)
                {
                    grid[x, y] = new Grass(new Coords(x,y));
                }
            }
            foreach(XmlNode objectNode in node.SelectNodes("/Map/Objects/Object"))
            {
                XmlNode positionNode;
                int x;
                int y;
                var dupa = objectNode.SelectSingleNode("Type").InnerText.Trim();
                switch (dupa)
                {
                    case "Road":
                        positionNode = objectNode.SelectSingleNode("Position");
                        x = Convert.ToInt32(positionNode.SelectSingleNode("X").InnerText);
                        y = Convert.ToInt32(positionNode.SelectSingleNode("Y").InnerText);
                        Road1 road = new Road1(new Coords(x,y));
                        grid[x, y] = road;
                        break;
                    case "House":
                        positionNode = objectNode.SelectSingleNode("Position");
                        x = Convert.ToInt32(positionNode.SelectSingleNode("X").InnerText);
                        y = Convert.ToInt32(positionNode.SelectSingleNode("Y").InnerText);
                        List<TrashCan> trashCans = new List<TrashCan>();
                        foreach (XmlNode trashCanNode in objectNode.SelectNodes("TrashCans/Can"))
                        {
                            GarbageType type;
                            switch (trashCanNode.SelectSingleNode("GarbageType").InnerText.Trim())
                            {
                                case "Glass":
                                    type = GarbageType.Glass;
                                    break;
                                case "Organic":
                                    type = GarbageType.Organic;
                                    break;
                                case "Paper":
                                    type = GarbageType.Paper;
                                    break;
                                default:
                                    type = GarbageType.PlasticMetal;
                                    break;
                            }
                            int canDensity = Convert.ToInt32(trashCanNode.SelectSingleNode("Density").InnerText);
                            int canProcessingTimePerUnit = Convert.ToInt32(trashCanNode.SelectSingleNode("ProcessingTimePerUnit").InnerText);
                            int volume = Convert.ToInt32(trashCanNode.SelectSingleNode("Volume").InnerText);
                            TypeOfGarbage canTypeOfGarbage = new TypeOfGarbage(type, canDensity,canProcessingTimePerUnit);
                            TrashCan trashCan = new TrashCan(canTypeOfGarbage, volume, new BasicGarbage(canTypeOfGarbage, volume));
                            trashCans.Add(trashCan);
                        }
                        House house = new House(new Coords(x,y), trashCans);
                        grid[x, y] = house;
                        break;
                    case "Dump":
                        positionNode = objectNode.SelectSingleNode("Position");
                        x = Convert.ToInt32(positionNode.SelectSingleNode("X").InnerText);
                        y = Convert.ToInt32(positionNode.SelectSingleNode("Y").InnerText);
                        XmlNode garbageNode = objectNode.SelectSingleNode("Garbage");
                        TypeOfGarbage typeOfGarbage;
                        GarbageType garbageType;
                        switch (garbageNode.SelectSingleNode("GarbageType").InnerText.Trim())
                        {
                            case "Glass":
                                garbageType = GarbageType.Glass;
                                break;
                            case "Organic":
                                garbageType = GarbageType.Organic;
                                break;
                            case "Paper":
                                garbageType = GarbageType.Paper;
                                break;
                            default:
                                garbageType = GarbageType.PlasticMetal;
                                break;
                        }

                        int density = Convert.ToInt32(garbageNode.SelectSingleNode("Density").InnerText);
                        int processingTimePerUnit = Convert.ToInt32(garbageNode.SelectSingleNode("ProcessingTimePerUnit").InnerText);
                        int maxVolume = Convert.ToInt32(objectNode.SelectSingleNode("Volume").InnerText);
                        typeOfGarbage = new TypeOfGarbage(garbageType, density, processingTimePerUnit);
                        Dump dump = new Dump(typeOfGarbage, maxVolume, new Coords(x, y));
                        grid[x, y] = dump;
                        break;
                }
            }
        }
    }
}