using ActionGame.GameResources.Models;
using ActionGame.RawResources.Models;
using GameMaker.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace GameMaker.Logic
{
    public class SessionSaver
    {


        public SessionSaver()
        {

        }


        public Exception Save(Session session)
        {
            //Save Raw Resources
            try
            {
                SaveRaw(session.WorkingDirectory, session.Fonts, "fonts.csv");
                SaveRaw(session.WorkingDirectory, session.Songs, "songs.csv");
                SaveRaw(session.WorkingDirectory, session.Textures, "textures.csv");
                SaveRaw(session.WorkingDirectory, session.SoundEffects, "soundeffects.csv");
            }
            catch(Exception e)
            {
                return e;
            }

            //Save Game Resources
            SaveTileSet(session.WorkingDirectory, session.TileSets, "tilesets.csv");
            SaveCharacterSet(session.WorkingDirectory, session.CharacterSets, "charactersets.csv");
            SaveWorlds(session.WorkingDirectory, session.Worlds, "worldmaps.csv");
            SavePlayer(session.WorkingDirectory, session.Player, "player.csv");
            SaveEnemies(session.WorkingDirectory, session.Enemies, "enemies.csv");
            SaveItems(session.WorkingDirectory, session.Items, "items.csv");

            return null;
        }


        private void SaveRaw(String workingDirectory, IList<RawResource> list, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\RawResources\\" + csvFile, false);

            writer.WriteLine(RawResource.GetCsvTitle());

            foreach(RawResource resource in list)
            {
                writer.WriteLine(resource.ToCsvString());
            }

            writer.Close();
        }


        private void SaveTileSet(String workingDirectory, IList<TileSetDefinition> list, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine(TileSetDefinition.GetCsvTitle());

            foreach(TileSetDefinition tileSet in list)
            {
                writer.WriteLine(tileSet.ToCsvString());
            }

            writer.Close();
        }


        private void SaveCharacterSet(String workingDirectory, IList<CharacterSetDefinition> list, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine(TileSetDefinition.GetCsvTitle());

            foreach (CharacterSetDefinition characterSet in list)
            {
                writer.WriteLine(characterSet.ToCsvString());
            }

            writer.Close();
        }


        private void SaveWorlds(String workingDirectory, IList<WorldDefinition> list, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine(WorldDefinition.GetCsvTitle());

            foreach (WorldDefinition worldDefinition in list)
            {
                writer.WriteLine(worldDefinition.ToCsvString());
            }

            writer.Close();

            //save each world
            foreach (WorldDefinition worldDefinition in list)
            {
                SaveWorld(workingDirectory, worldDefinition);
            }
        }


        private void SaveWorld(String workingDirectory, WorldDefinition worldDefinition)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + worldDefinition.Filename, false);

            foreach(WorldCellDefinition worldCell in worldDefinition.Cells)
            {
                writer.WriteLine("Cell|" + worldCell.WorldX + "|" + worldCell.WorldY + "|" + worldCell.SongKey);

                //tiles
                foreach (int yKey in worldCell.TilesLayer1[0].Keys)
                {
                    StringBuilder line = new StringBuilder();

                    foreach (int xKey in worldCell.TilesLayer1.Keys)
                    {
                        Int32? tile1 = worldCell.TilesLayer1[xKey][yKey];
                        Int32? tile2 = worldCell.TilesLayer2[xKey][yKey];

                        if (line.Length != 0)
                        {
                            line.Append(",");
                        }

                        if (tile1 != null) line.Append(tile1);

                        if (tile2 != null)
                        {
                            line.Append("|");
                            line.Append(tile2);
                        }
                    }

                    writer.WriteLine(line);
                }

                //doors
                foreach(DoorDefinition door in worldCell.Doors)
                {
                    writer.WriteLine(door.ToCsvString());
                }

                //npcs
                foreach(NonPlayerCharacterDefinition npc in worldCell.NPCs)
                {
                    writer.WriteLine(npc.ToCsvString());
                }

                //enemy placements
                foreach(EnemyDefinitionPlacement enemyPlacement in worldCell.EnemyDefinitionPlacements)
                {
                    writer.WriteLine(enemyPlacement.ToCsvString());
                }
            }

            writer.Close();
        }


        private void SavePlayer(String workingDirectory, PlayerDefinition playerDefinition, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine("Key,Value");
            writer.WriteLine("CharacterSetKey," + playerDefinition.CharacterSetKey);
            writer.WriteLine("StartMap," + playerDefinition.StartPosition.WorldMapKey);
            writer.WriteLine("StartCellX," + playerDefinition.StartPosition.WorldCellX);
            writer.WriteLine("StartCellY," + playerDefinition.StartPosition.WorldCellY);
            writer.WriteLine("StartTileX," + playerDefinition.StartPosition.PositionX);
            writer.WriteLine("StartTileY," + playerDefinition.StartPosition.PositionY);
            writer.WriteLine("Health," + playerDefinition.Health);
            writer.WriteLine("Attack," + playerDefinition.Attack);
            writer.WriteLine("Defence," + playerDefinition.Defence);

            writer.Close();
        }


        private void SaveEnemies(String workingDirectory, IList<EnemyDefinition> enemyDefinitions, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine(EnemyDefinition.GetCsvTitle());

            foreach(EnemyDefinition enemy in enemyDefinitions)
            {
                writer.WriteLine(enemy.ToCsvString());
            }

            writer.Close();
        }


        private void SaveItems(String workingDirectory, IList<ItemDefinition> itemDefinitions, String csvFile)
        {
            StreamWriter writer = new StreamWriter(workingDirectory + "\\GameResources\\" + csvFile, false);

            writer.WriteLine(ItemDefinition.GetCsvTitle());

            foreach (ItemDefinition item in itemDefinitions)
            {
                writer.WriteLine(item.ToCsvString());
            }

            writer.Close();
        }

    }
}
