﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Uber.Messages;
using Uber.Util;

namespace Uber.HabboHotel.Rooms
{
    public enum SquareState
    {
        OPEN = 0,
        BLOCKED = 1,
        SEAT = 2
    }

    class RoomModel
    {
        public string Name;

        public int DoorX;
        public int DoorY;
        public double DoorZ;
        public int DoorOrientation;

        public string Heightmap;

        public SquareState[,] SqState;
        public double[,] SqFloorHeight;
        public int[,] SqSeatRot;

        public int MapSizeX;
        public int MapSizeY;

        public string StaticFurniMap;

        public bool ClubOnly;

        public RoomModel(string Name, int DoorX, int DoorY, double DoorZ, int DoorOrientation, string Heightmap, string StaticFurniMap, bool ClubOnly)
        {
            this.Name = Name;

            this.DoorX = DoorX;
            this.DoorY = DoorY;
            this.DoorZ = DoorZ;
            this.DoorOrientation = DoorOrientation;

            this.Heightmap = Heightmap.ToLower();
            this.StaticFurniMap = StaticFurniMap;

            string[] tmpHeightmap = Heightmap.Split(Convert.ToChar(13));

            this.MapSizeX = tmpHeightmap[0].Length;
            this.MapSizeY = tmpHeightmap.Length;

            this.ClubOnly = ClubOnly;

            SqState = new SquareState[MapSizeX, MapSizeY];
            SqFloorHeight = new double[MapSizeX, MapSizeY];
            SqSeatRot = new int[MapSizeX, MapSizeY];

            for (int y = 0; y < MapSizeY; y++)
            {
                if (y > 0)
                {
                    tmpHeightmap[y] = tmpHeightmap[y].Substring(1);
                }

                for (int x = 0; x < MapSizeX; x++)
                {
                    string Square = tmpHeightmap[y].Substring(x, 1).Trim().ToLower();

                    if (Square == "x")
                    {
                        SqState[x, y] = SquareState.BLOCKED;
                    }
                    else if (isNumeric(Square, System.Globalization.NumberStyles.Integer))
                    {
                        SqState[x, y] = SquareState.OPEN;
                        SqFloorHeight[x, y] = double.Parse(Square);
                    }
                }
            }

            SqFloorHeight[DoorX, DoorY] = DoorZ;

            // SOHd1017benchQDRBHJHd1019benchSDRBHRAHd1021benchQERBHJHd1023benchSERBHRAHd1117benchQDSBHJHd1119benchSDSBHRAHd1121benchQESBHJHd1123benchSESBHRAHb1132koc_chairPHSBIPAHd1217benchQDPCHJHd1219benchSDPCHRAHd1221benchQEPCHJHd1223benchSEPCHRAHb1231koc_chairSGPCIJHa1232koc_tablePHPCIHHb1233koc_chairQHPCIRAHd1317benchQDQCHJHd1319benchSDQCHRAHd1321benchQEQCHJHd1323benchSEQCHRAHb1325koc_chairQFQCIPAHb1332koc_chairPHQCIHHd1417benchQDRCHJHd1419benchSDRCHRAHd1421benchQERCHJHd1423benchSERCHRAHa1425koc_tableQFRCIHHb1426koc_chairRFRCIRAHd1517benchQDSCHJHd1519benchSDSCHRAHd1521benchQESCHJHd1523benchSESCHRAHb1525koc_chairQFSCIHHb1529koc_chairQGSCIJHa1530koc_tableRGSCIHHb1531koc_chairSGSCIRAHb1630koc_chairRGPDIHHc2425chairf1QFPFIJHc2433chairf1QHPFIRAHd2517benchQDQFHJHd2519benchSDQFHRAHd2521benchQEQFHJHd2523benchSEQFHRAHc2525chairf1QFQFIJHc2533chairf1QHQFIRAHd2617benchQDRFHJHd2619benchSDRFHRAHd2621benchQERFHJHd2623benchSERFHRAHc2625chairf1QFRFIJHc2633chairf1QHRFIRAHd2717benchQDSFHJHd2719benchSDSFHRAHd2721benchQESFHJHd2723benchSESFHRAHd2817benchQDPGHJHd2819benchSDPGHRAHd2821benchQEPGHJHd2823benchSEPGHRAHd2917benchQDQGHJHd2919benchSDQGHRAHd2921benchQEQGHJHd2923benchSEQG`hFFRA

            string tmpFurnimap = StaticFurniMap;
            int pointer = 0;

            int num = OldEncoding.decodeVL64(tmpFurnimap);
            pointer += OldEncoding.encodeVL64(num).Length;

            for (int i = 0; i < num; i++)
            {
                string thisss = tmpFurnimap.Substring(pointer);

                int junk = OldEncoding.decodeVL64(tmpFurnimap.Substring(pointer)); // probably not junk, but dunno what it is
                pointer += OldEncoding.encodeVL64(junk).Length;

                string junk2 = tmpFurnimap.Substring(pointer, 1); // probably not junk, but dunno what it is
                pointer += 1;

                int junk3 = int.Parse(tmpFurnimap.Substring(pointer).Split(Convert.ToChar(2))[0]); // probably not junk, but dunno what it is
                pointer += tmpFurnimap.Substring(pointer).Split(Convert.ToChar(2))[0].Length;

                pointer += 1;

                string name = tmpFurnimap.Substring(pointer).Split(Convert.ToChar(2))[0];
                pointer += tmpFurnimap.Substring(pointer).Split(Convert.ToChar(2))[0].Length;

                pointer += 1;

                int x = OldEncoding.decodeVL64(tmpFurnimap.Substring(pointer));
                pointer += OldEncoding.encodeVL64(x).Length;

                int y = OldEncoding.decodeVL64(tmpFurnimap.Substring(pointer));
                pointer += OldEncoding.encodeVL64(y).Length;

                int junk4 = OldEncoding.decodeVL64(tmpFurnimap.Substring(pointer)); // probably not junk, but dunno what it is
                pointer += OldEncoding.encodeVL64(junk4).Length;

                int junk5 = OldEncoding.decodeVL64(tmpFurnimap.Substring(pointer)); // probably not junk, but dunno what it is
                pointer += OldEncoding.encodeVL64(junk5).Length;

                SqState[x, y] = SquareState.BLOCKED;

                if (name.Contains("bench") || name.Contains("chair") || name.Contains("stool") ||
                    name.Contains("seat") || name.Contains("sofa"))
                {
                    SqState[x, y] = SquareState.SEAT;
                    SqSeatRot[x, y] = junk5;
                }
            }
        }

        public bool isNumeric(string val, System.Globalization.NumberStyles NumberStyle)
        {
            Double result;
            return Double.TryParse(val, NumberStyle,
                System.Globalization.CultureInfo.CurrentCulture, out result);
        }

        public ServerMessage SerializeHeightmap()
        {
            StringBuilder HeightMap = new StringBuilder();

            foreach (string MapBit in Heightmap.Split("\r\n".ToCharArray()))
            {
                if (MapBit == "")
                {
                    continue;
                }

                HeightMap.Append(MapBit);
                HeightMap.Append(Convert.ToChar(13));
            }

            ServerMessage Message = new ServerMessage(31);
            Message.AppendStringWithBreak(HeightMap.ToString());
            return Message;
        }

        public ServerMessage SerializeRelativeHeightmap()
        {
            ServerMessage Message = new ServerMessage(470);

            string[] tmpHeightmap = Heightmap.Split(Convert.ToChar(13));

            for (int y = 0; y < MapSizeY; y++)
            {
                if (y > 0)
                {
                    tmpHeightmap[y] = tmpHeightmap[y].Substring(1);
                }

                for (int x = 0; x < MapSizeX; x++)
                {
                    string Square = tmpHeightmap[y].Substring(x, 1).Trim().ToLower();

                    if (DoorX == x && DoorY == y)
                    {
                        Square = (int)DoorZ + "";
                    }

                    Message.AppendString(Square);
                }

                Message.AppendString("" + Convert.ToChar(13));
            }

            return Message;
        }
    }
}
