using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using UnityEngine;

public class Location
{
    public uint company_id;
    public uint id { get; set; }
    public string name { get; set; }
    public List<Wall> walls { get; set; }
    public List<Beacon> beacons { get; set; }
    public GameObject plane { get; set; }
    public string texture_url { get; set; }
    public List<Zone> zones { get; set; }
    public GameObject location { get; set; }
    public static List<string> contents = new List<string> { "Walls", "Zones", "Beacons" };

    public void Save()
    {
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        var urlb = Encoding.UTF8.GetBytes(texture_url);
        ushort urllen = (ushort)urlb.Length;
        bw.Write(id);
        bw.Write(plane.transform.localScale.x);
        bw.Write(plane.transform.localScale.z);
        bw.Write(plane.transform.localPosition.x);
        bw.Write(plane.transform.localPosition.z);
        bw.Write(company_id);       
        bw.Write(urllen);
        bw.Write(urlb);

        //ms.Write(bdata, 0, bdata.Length);
        //Debug.Log("imagesend bytes "+ms.ToArray().Length);
        var data = Client.ConstructVariablePacket(56, ms.ToArray());
        Client.SendEnqueue(data);
    }

    public static void TextureGetURL(byte[] bytedata)
    {
        var loc_id = BitConverter.ToUInt32(bytedata, 5);
        var urllen = bytedata.Length - 9;
        var loc = CompanyController.instance.GetLocation(loc_id);
        var url = Encoding.UTF8.GetString(bytedata, 9, urllen);
        loc.texture_url = url;
        loc.Save();
        //Debug.Log("get url " + url+" loc_id "+loc.id);
    }    

    public void SaveTexture(byte[] img)
    {
        Debug.Log("SaveTexture");
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        bw.Write(id);
        bw.Write(img);
        Client.SendEnqueue(Client.ConstructVariablePacket(57, ms.ToArray()));
    }

    public void SaveContents()
    {
        foreach (Wall wall in walls)
        {
            wall.Save();
        }
        foreach (var z in zones)
        {
            z.Save();
        }
        Beacon.Save(beacons);
    }

    public void Load()
    {
        Debug.Log("Location.Load");
        Zone.LoadByLocationId(id);
        Wall.LoadByLocationId(id);
        Beacon.Request(id);
        //Client.instance.SendGetUsers();
    }

    public static void LocationsRequest(uint companyId=0)
    {
        if (companyId == 0)
            companyId = Client.instance.company_id;
        Client.SendFourByteParamPacket(54, companyId);
    }

    public static void ReceiveLocations(byte[] bytedata)
    {
        var company = CompanyController.instance;
        company.locations = new Dictionary<uint, Location>();
        company.locations_index = new List<uint>();

        int read = 5;
        while (read < bytedata.Length)
        {
            var id = BitConverter.ToUInt32(bytedata, read);
            var x = BitConverter.ToSingle(bytedata, read + 4);
            var y = BitConverter.ToSingle(bytedata, read + 8);
            var scalex = BitConverter.ToSingle(bytedata, read + 12);
            var scalez = BitConverter.ToSingle(bytedata, read + 16);
            var posx = BitConverter.ToSingle(bytedata, read + 20);
            var posz = BitConverter.ToSingle(bytedata, read + 24);
            var lenimg = BitConverter.ToUInt16(bytedata, read + 28);
            var img = Encoding.UTF8.GetString(bytedata, read + 30, lenimg);
            var lenname = BitConverter.ToUInt16(bytedata, read + 30 + lenimg);
            var name = Encoding.UTF8.GetString(bytedata, read + 32 + lenimg, lenname);
            var company_id = BitConverter.ToUInt32(bytedata, read + 32 + lenimg + lenname);
            read += (36 + lenimg + lenname);
            Debug.Log($"location received company_id {company_id} read {read} id {id} x {x} y {y} scalex {scalex} scalez {scalez} posx {posx} posz {posz} lenimg {lenimg} img {img} lenname {lenname} name {name}");

            var plane = UnityEngine.Object.Instantiate(Resources.Load("GameObjects/Plane", typeof(GameObject))) as GameObject;
           
            if (scalex == 0) scalex = 1; if (scalez == 0) scalez = 1;
            plane.transform.localScale = new Vector3(scalex, WallCreate.WallHeight, scalez);
            if (posx == 0) posx = scalex / 2; if (posz == 0) posz = scalez / 2;
            plane.transform.position = new Vector3(posx, 0.01f, posz);            

            var Location = new GameObject();
            Location.name = name;

            plane.transform.SetParent(Location.transform);
            
            foreach (var g in contents)
            {
                var go = new GameObject();
                go.name = g;
                go.transform.SetParent(Location.transform);
            }          

            company.locations[id] =new Location { id = id, name = name, texture_url = img, location = Location, plane = plane, company_id = company_id };
            company.locations_index.Add(id);
            Debug.Log("locations count "+ company.locations.Count);
        }
        company.load_location = true;
    }

    public void LocationActive(bool active, LocationZones lzs)
    {
        location.SetActive(active);
        if (beacons != null)
            foreach (var b in beacons)
                if (b.panel_button != null)
                    b.panel_button.SetActive(active);
        if (zones != null)
            foreach (var z in zones)
                if (z.buttons != null)
                {
                    z.buttons.SetActive(active);

                    var lz = lzs.ZoneInfos[z.id];
                    lz.gameObject.SetActive(active);
                }
        if (active)
        {
            Camera.main.GetComponent<CameraController>().location = plane;
            Camera.main.GetComponent<CameraController>().CameraCenter();
        }
    }
}

