using System;
using System.IO;

namespace Map_Extractor
{
    public class Statics
    {
        private int _fileIndex;
        public int FileIndex { get { return _fileIndex; } }

        private int _width;
        public int Width { get { return _width; } }

        private int _height;
        public int Height { get { return _height; } }

        private FileStream fsIDX;
        private FileStream fsStatics;

        private int position = 0;

        public Statics(int fileindex, int width, int height)
        {
            _fileIndex = fileindex;
            _width = width / 8;
            _height = height / 8;
        }

        public bool OpenStatics(string path, bool writing)
        {
            if (!writing || !Parameters.EntireMap)
            {
                if (!File.Exists(String.Format("{0}\\staidx{1}.mul", path, FileIndex)))
                    return false;

                if (!File.Exists(String.Format("{0}\\statics{1}.mul", path, FileIndex)))
                    return false;
            }

            FileMode mode = FileMode.Open;

            if (writing && Parameters.EntireMap)
                mode = FileMode.Create;
            else
                mode = FileMode.OpenOrCreate;

            try
            {
                fsIDX = new FileStream(String.Format("{0}\\staidx{1}.mul", path, FileIndex), mode);
                fsStatics = new FileStream(String.Format("{0}\\statics{1}.mul", path, FileIndex), mode);

                return (writing ? fsStatics.CanWrite : fsStatics.CanRead);
            }
            catch { return false; }
        }

        public void Close()
        {
            try
            {
                fsIDX.Close();
                fsStatics.Close();
            }
            catch { }
        }

        public IDX ReadBlock(int x,int y)
        {
            try
            {
                fsIDX.Position = ((x * Height) + y) * 12;
                BinaryReader readerIDX = new BinaryReader(fsIDX);

                IDX idx = new IDX(readerIDX.ReadUInt32(), readerIDX.ReadUInt32(), readerIDX.ReadUInt32());

                if (idx.Start != 0xFFFFFFFF)
                {
                    idx.Statics = new StaticDef[idx.Length / 7];

                    fsStatics.Position = idx.Start;
                    BinaryReader readerStatics = new BinaryReader(fsStatics);

                    for (int xx = 0; xx < idx.Statics.Length; xx++)
                    {
                        idx.Statics[xx] = new StaticDef(readerStatics.ReadUInt16(), readerStatics.ReadByte(), readerStatics.ReadByte(),
                            readerStatics.ReadSByte(), readerStatics.ReadInt16());

                        try
                        {
                            if (Parameters.ItemConversions[idx.Statics[xx].Color] != null)
                                idx.Statics[xx].Color = (UInt16)Parameters.ItemConversions[idx.Statics[xx].Color];
                        }
                        catch { }
                    }
                }

                int realItems = 0;

                foreach (StaticDef sd in idx.Statics)
                    if (sd.Color != 65535)
                        realItems++;

                if (realItems != idx.Statics.Length)
                {
                    StaticDef[] newStatics = new StaticDef[realItems];
                    int counter = 0;

                    foreach (StaticDef sd in idx.Statics)
                        if (sd.Color != 65535)
                        {
                            newStatics[counter] = sd;
                            counter++;
                        }

                    idx.Statics = newStatics;
                }

                return idx;
            }
            catch { return new IDX(0xFFFFFFFF, 0, 0); }
        }

        public void WriteBlock(IDX idx, int x, int y)
        {
            try
            {
                fsIDX.Position = ((x * Height) + y) * 12;
                BinaryWriter writerIDX = new BinaryWriter(fsIDX);

                writerIDX.Write((UInt32)position);
                writerIDX.Write((UInt32)(idx.Statics.Length * 7));
                writerIDX.Write((UInt32)idx.Trailer);

                fsStatics.Position = position;
                BinaryWriter writerStatics = new BinaryWriter(fsStatics);

                foreach (StaticDef sd in idx.Statics)
                {
                    writerStatics.Write((UInt16)sd.Color);
                    writerStatics.Write((Byte)sd.X);
                    writerStatics.Write((Byte)sd.Y);
                    writerStatics.Write((SByte)sd.Altitude);
                    writerStatics.Write((Int16)sd.Trailer);

                    position += 7;
                }
            }
            catch { }
        }

        public void WriteEmptyBlock(int x, int y)
        {
            WriteBlock(new IDX(0xFFFFFFFF, 0, 0), x, y);
        }

        public void ClearStaticArea()
        {
            if (Parameters.EntireMap)
                return;

            try
            {
                IDX[,] oldTiles = new IDX[Width, Height];

                for (int x = 0; x < Width; x++)
                {
                    for (int y = 0; y < Height; y++)
                    {
                        if (x >= Parameters.DestinationLocation.X && x < Parameters.DestinationLocation.X + Parameters.SourceArea.Width &&
                            y >= Parameters.DestinationLocation.Y && x < Parameters.DestinationLocation.Y + Parameters.SourceArea.Height)
                        {
                            oldTiles[x, y] = new IDX(0xFFFFFFFF, 0, 0);
                        }
                        else
                        {
                            oldTiles[x, y] = ReadBlock(x, y);
                        }
                    }
                }

                position = 0;


                for (int x = 0; x < Width; x++)
                {
                    for (int y = 0; y < Height; y++)
                    {
                        WriteBlock(oldTiles[x, y], x, y);
                    }
                }
            }
            catch { }
        }
    }
}