﻿using System;
using System.Collections.Generic;
using Roguelike.Core.Elements.Inventory;
using Roguelike.Entities;
using RLNET;

namespace Roguelike.Systems {
    public class InventorySystem {

        private Player player;

        public InventorySystem() {
            player = Game.Player;
        }

        void SelectEquipment(Equipment pressedOn) {
            if (pressedOn.GetType() == typeof(HeadEquipment)) {
                SelectHeadEquipment((HeadEquipment)pressedOn);
            } else if (pressedOn.GetType() == typeof(BodyEquipment)) {
                SelectBodyEquipment((BodyEquipment)pressedOn);
            } else if (pressedOn.GetType() == typeof(ArmEquipment)) {
                SelectArmEquipment((ArmEquipment)pressedOn);
            } else if (pressedOn.GetType() == typeof(LegEquipment)) {
                SelectLegEquipment((LegEquipment)pressedOn);
            } else if (pressedOn.GetType() == typeof(HandEquipment)) {
                SelectHandEquipment((HandEquipment)pressedOn);
            } else if (pressedOn.GetType() == typeof(FeetEquipment)) {
                SelectFeetEquipment((FeetEquipment)pressedOn);
            }
            Game.Render();
        }

        void DiscardEquipment(Equipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            Game.Render();
        }

        void SelectHeadEquipment(HeadEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if(player.Head != null && player.Head != HeadEquipment.None()) {
                player.AddEquipment(player.Head);
            }
            player.Head = pressedOn;
        }

        void SelectBodyEquipment(BodyEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if (player.Body != null && player.Body != BodyEquipment.None()) {
                player.AddEquipment(player.Body);
            }
            player.Body = pressedOn;
        }

        void SelectArmEquipment(ArmEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if (player.Arms != null && player.Arms != ArmEquipment.None()) {
                player.AddEquipment(player.Arms);
            }
            player.Arms = pressedOn;
        }

        void SelectLegEquipment(LegEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if (player.Legs != null && player.Legs != LegEquipment.None()) {
                player.AddEquipment(player.Legs);
            }
            player.Legs = pressedOn;
        }

        void SelectHandEquipment(HandEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if (player.Hands != null && player.Hands != HandEquipment.None()) {
                player.AddEquipment(player.Hands);
            }
            player.Hands = pressedOn;
        }

        void SelectFeetEquipment(FeetEquipment pressedOn) {
            player.equipmentInInventory.Remove(pressedOn);
            if (player.Feet != null && player.Feet != FeetEquipment.None()) {
                player.AddEquipment(player.Feet);
            }
            player.Feet = pressedOn;
        }

        public Equipment EquipArmourFromInventory(int x, int y) {
            for (int i = 0; i < player.equipmentInInventory.Count; i++) {
                int lengthOfString = player.equipmentInInventory[i].Name.Length;

                int numberOfLines = 0;
                if(lengthOfString >= 20) {
                    numberOfLines = 2;
                } else {
                    numberOfLines = 1;
                }

                int xStartPosition = 0;
                int yPosition = (3 * i) + 3;
                if(i < 6) {
                    xStartPosition = 22;
                } else {
                    yPosition = (3 * i) - 15;
                    xStartPosition = 44;
                }
                if(numberOfLines == 1) {
                    if(x >= xStartPosition && x < xStartPosition + lengthOfString && y == yPosition) {
                        SelectEquipment(player.equipmentInInventory[i]);
                    }
                }else if(numberOfLines == 2) {
                    string topString = TopLine(player.equipmentInInventory[i].Name);
                    string bottomString = BottomLine(player.equipmentInInventory[i].Name, topString);
                    if(y == yPosition) {
                        if(x >= xStartPosition && x < xStartPosition + topString.Length - 1) {
                            SelectEquipment(player.equipmentInInventory[i]);
                        }
                    } else if(y == yPosition + 1) {
                        if (x >= xStartPosition && x < xStartPosition + bottomString.Length) {
                            SelectEquipment(player.equipmentInInventory[i]);
                        }
                    }
                }
            }
            return null;
        }

        public void DiscardArmourFromInventory(int x, int y) {
            for (int i = 0; i < player.equipmentInInventory.Count; i++) {
                int lengthOfString = player.equipmentInInventory[i].Name.Length;

                int numberOfLines = 0;
                if (lengthOfString >= 20) {
                    numberOfLines = 2;
                } else {
                    numberOfLines = 1;
                }

                int xStartPosition = 0;
                int yPosition = (3 * i) + 3;
                if (i < 6) {
                    xStartPosition = 22;
                } else {
                    yPosition = (3 * i) - 15;
                    xStartPosition = 44;
                }
                if (numberOfLines == 1) {
                    if (x >= xStartPosition && x < xStartPosition + lengthOfString && y == yPosition) {
                        DiscardEquipment(player.equipmentInInventory[i]);
                    }
                } else if (numberOfLines == 2) {
                    string topString = TopLine(player.equipmentInInventory[i].Name);
                    string bottomString = BottomLine(player.equipmentInInventory[i].Name, topString);
                    if (y == yPosition) {
                        if (x >= xStartPosition && x < xStartPosition + topString.Length - 1) {
                            DiscardEquipment(player.equipmentInInventory[i]);
                        }
                    } else if (y == yPosition + 1) {
                        if (x >= xStartPosition && x < xStartPosition + bottomString.Length) {
                            DiscardEquipment(player.equipmentInInventory[i]);
                        }
                    }
                }
            }
        }

        public void RemoveEquipment(int x, int y) {
            if (y == 3) {
                if (x >= 1 && x <= 14) {
                    HeadEquipment toRemove = player.Head;
                    player.Head = HeadEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                } else if (x > 14 && x < 28) {
                    LegEquipment toRemove = player.Legs;
                    player.Legs = LegEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                }
            } else if (y == 5) {
                if (x >= 1 && x <= 14) {
                    BodyEquipment toRemove = player.Body;
                    player.Body = BodyEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                } else if (x > 14 && x < 28) {
                    HandEquipment toRemove = player.Hands;
                    player.Hands = HandEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                }
            } else if (y == 7) {
                if (x >= 1 && x <= 14) {
                    ArmEquipment toRemove = player.Arms;
                    player.Arms = ArmEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                } else if (x > 14 && x < 28) {
                    FeetEquipment toRemove = player.Feet;
                    player.Feet = FeetEquipment.None();
                    player.equipmentInInventory.Add(toRemove);
                }
            }
            Game.Render();
        }

        public Equipment RemoveCurrentArmour(int x, int y) {
            if(y == 3 || y == 4) {
                ClickedOnHead(x, y);
            } else if(y == 6 || y == 7) {
                ClickedOnBody(x, y);
            } else if (y == 9 || y == 10) {
                ClickedOnArms(x, y);
            } else if (y == 12 || y == 13) {
                ClickedOnLegs(x, y);
            } else if (y == 15 || y == 16) {
                ClickedOnHands(x, y);
            } else if (y == 18 || y == 19) {
                ClickedOnFeet(x, y);
            }
            return null;
        }

        private void ClickedOnHead(int x, int y) {
            string topLine = TopLine("Head: " + player.Head.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Head: " + player.Head.Name, topLine);
            } catch {
            }
            if (y == 4) {
                if (bottomLine != "") {
                    if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                        UnequipArmour(player.Head);
                    }
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Head);
                }
            }
        }

        public void ClickedOnBody(int x, int y) {
            string topLine = TopLine("Body: " + player.Body.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Body: " + player.Body.Name, topLine);
            } catch {
            }
            if (y == 7) {
                if (bottomLine != "") {
                    if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                        UnequipArmour(player.Body);
                    }
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Body);
                }
            }
        }

        public void ClickedOnArms(int x, int y) {
            string topLine = TopLine("Arms: " + player.Arms.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Arms: " + player.Arms.Name, topLine);
            } catch {
            }
            if (y == 10) {
                if (bottomLine != "") {
                    if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                        UnequipArmour(player.Arms);
                    }
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Arms);
                }
            }
        }

        public void ClickedOnLegs(int x, int y) {
            string topLine = TopLine("Legs: " + player.Legs.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Legs: " + player.Legs.Name, topLine);
            } catch {
            }
            if (y == 13) {
                if (bottomLine != "") {
                    if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                        UnequipArmour(player.Legs);
                    }
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Legs);
                }
            }
        }

        public void ClickedOnHands(int x, int y) {
            string topLine = TopLine("Hands: " + player.Hands.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Hands: " + player.Hands.Name, topLine);
            } catch {
            }
            if (y == 16) {
                if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                    UnequipArmour(player.Hands);
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Hands);
                }
            }
        }

        private void ClickedOnFeet(int x, int y) {
            string topLine = TopLine("Feet: " + player.Feet.Name, 20);
            string bottomLine = "";
            try {
                bottomLine = BottomLine("Feet: " + player.Feet.Name, topLine);
            } catch {
            }
            if (y == 19) {
                if (DidClickOnString(x, y, true, topLine, bottomLine)) {
                    UnequipArmour(player.Feet);
                }
            } else {
                if (DidClickOnString(x, y, false, topLine, bottomLine)) {
                    UnequipArmour(player.Feet);
                }
            }
        }

        public bool DidClickOnString(int x, int  y, bool secondLine,string topLine, string bottomLine = "") {
            int xStartPosition = 1;
            int topXEndPosition = xStartPosition + topLine.Length;
            int bottomXEndPosition = xStartPosition + bottomLine.Length;
            if (bottomLine != "") {
                if (secondLine) {
                    if (x >= xStartPosition && x <= bottomXEndPosition) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    if (x >= xStartPosition && x <= topXEndPosition) {
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                if(x >= xStartPosition && x <= topXEndPosition) {
                    return true;
                } else {
                    return false;
                }
            }
        }

        private void UnequipArmour(Equipment toUnequip) {
            if (toUnequip.GetType() == typeof(HeadEquipment) && toUnequip != HeadEquipment.None()) {
                UnSelectHeadEquipment((HeadEquipment)toUnequip);
            } else if (toUnequip.GetType() == typeof(BodyEquipment) && toUnequip != BodyEquipment.None()) {
                UnSelectBodyEquipment((BodyEquipment)toUnequip);
            } else if (toUnequip.GetType() == typeof(ArmEquipment) && toUnequip != ArmEquipment.None()) {
                UnSelectArmEquipment((ArmEquipment)toUnequip);
            } else if (toUnequip.GetType() == typeof(LegEquipment) && toUnequip != LegEquipment.None()) {
                UnSelectLegEquipment((LegEquipment)toUnequip);
            } else if (toUnequip.GetType() == typeof(HandEquipment) && toUnequip != HandEquipment.None()) {
                UnSelectHandEquipment((HandEquipment)toUnequip);
            } else if (toUnequip.GetType() == typeof(FeetEquipment) && toUnequip != FeetEquipment.None()) {
                UnSelectFeetEquipment((FeetEquipment)toUnequip);
            }
            Game.Render();
        }

        private void UnSelectHeadEquipment(HeadEquipment toUnequip) {
            if(player.equipmentInInventory.Count < 12) {
                player.Head = HeadEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private void UnSelectBodyEquipment(BodyEquipment toUnequip) {
            if (player.equipmentInInventory.Count < 12) {
                player.Body = BodyEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private void UnSelectArmEquipment(ArmEquipment toUnequip) {
            if (player.equipmentInInventory.Count < 12) {
                player.Arms = ArmEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private void UnSelectLegEquipment(LegEquipment toUnequip) {
            if (player.equipmentInInventory.Count < 12) {
                player.Legs = LegEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private void UnSelectHandEquipment(HandEquipment toUnequip) {
            if (player.equipmentInInventory.Count < 12) {
                player.Hands = HandEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private void UnSelectFeetEquipment(FeetEquipment toUnequip) {
            if (player.equipmentInInventory.Count < 12) {
                player.Feet = FeetEquipment.None();
                player.AddEquipment(toUnequip);
            }
        }

        private string TopLine(string totalString, int wrapLength = 18) {
            List<string> wordsInString = new List<string>();
            string currentString = "";
            for (int i = 0; i < totalString.Length; i++) {
                char character = totalString[i];
                if (character == ' ') {
                    wordsInString.Add(currentString);
                    currentString = "";
                }else if(i == totalString.Length - 1) {
                    currentString += character;
                    wordsInString.Add(currentString);
                    currentString = "";
                } else {
                    currentString += character;
                }
            }
            int lengthSoFar = 0;
            string topLine = "";
            for (int i = 0; i < wordsInString.Count; i++) {
                if (lengthSoFar + wordsInString[i].Length >= wrapLength) {
                    break;
                }
                lengthSoFar += wordsInString[i].Length;
                topLine += wordsInString[i];
                topLine += " ";
            }
            return topLine;
        }

        private string BottomLine(string totalString, string topLine) {
            string bottom = totalString;
            bottom = bottom.Substring(topLine.Length);
            return bottom;
        }

    }
}
