package net.cobem.grizzly.habbohotel.rooms.robots;

import gnu.trove.map.hash.THashMap;
import net.cobem.grizzly.Grizzly;
import net.cobem.grizzly.habbohotel.pathfinding.Position;
import net.cobem.grizzly.habbohotel.rooms.Room;
import net.cobem.grizzly.habbohotel.rooms.items.FloorItem;
import net.cobem.grizzly.utils.DateFormat;

import java.util.Collection;
import java.util.Date;
import java.util.Random;

public class RobotHandler {
    private Room Room;

    public THashMap<Integer, Robot> Robots;

    public RobotHandler(Room Room) {
        Robots = new THashMap<Integer, Robot>();

        this.Room = Room;
    }

    public void cycle() {
        for (Robot Robot : Robots.values()) {
            if (Robot.AI.Terminate) {
                continue; //Farewell..
            }

            if (Grizzly.getDateHandler().GetDateFrom(Robot.LastUpdate, DateFormat.Seconds) >= 5) {
                Boolean Talk = (new Random().nextInt(2) == 1);

                if (Talk) {
                    //Grizzly.WriteOut(Robot.Name + ": talks");
                    Robot.AI.sayPhrase();
                } else {
                    //Grizzly.WriteOut(Robot.Name + ": moves");
                    Robot.AI.move();
                }

                Robot.LastUpdate = new Date();
            }

            if (Robot.Status.contains("mv") && !Robot.AI.IsMoving) {
                Robot.updateStatus("");
            }

            if (Robot.AI.IsMoving) {
                Robot.LastUpdate = new Date(); //No new path needs to be done

                Collection<byte[]> Path = Robot.CurrentRoom.getPathfinder().Path(
                        (byte) Robot.X,
                        (byte) Robot.Y,
                        (byte) Robot.AI.NewX,
                        (byte) Robot.AI.NewY,
                        Grizzly.getHabboHotel().getRooms().MaxDrop,
                        Grizzly.getHabboHotel().getRooms().MaxJump);

                if (Path.size() == 0) {
                    Robot.AI.IsMoving = false;
                    return;
                }

                byte[] NextStep = null;
                byte[] NextNextStep = null;
                int Key = 0;

                for (byte[] Next : Path) {
                    if (Key == 0) {
                        NextStep = Next;
                        Key++;
                        continue;
                    }

                    if (Key == 1) {
                        NextNextStep = Next;
                        break;
                    }
                }

                FloorItem NextItem;

                try {
                    NextItem = Robot.CurrentRoom.getMap().GetItemAtPosition(new Position(NextStep[0], NextStep[1], 0));
                } catch (Exception Ex) {
                    NextItem = null;
                }

                Robot.Rotation = (new Position(Robot.X, Robot.Y, 0).Calculate(NextStep[0], NextStep[1]));

                if (NextItem != null) {
                    Robot.Height = NextItem.Height.intValue();
                } else {
                    Robot.Height = 0;
                }

                Room.getPositions().remove(Robot.ID);

                Room.getMap().UserCollisionMap[Robot.X][Robot.Y] = false;

                Robot.updateStatus("mv " + NextStep[0] + "," + NextStep[1] + "," + Double.toString(Robot.Height));
                Robot.X = NextStep[0];
                Robot.Y = NextStep[1];

                Room.getPositions().put(Robot.ID, new Position(Robot.X, Robot.Y, 0));

                if (NextNextStep == null) //It's the last!
                {
                    NextItem = Robot.CurrentRoom.getItemForInteraction(new Position(Robot.X, Robot.Y, 0));

                    if (NextItem != null) {
                        if (NextItem.getBase().Sitable) {
                            Robot.Rotation = NextItem.Rotation;

                            Robot.updateStatus("sit " + NextItem.getBase().StackHeight);
                        } else {
                            //Grizzly.GrabHabboHotel().GrabInteractionHandler().OnTrigger(NextItem.GetBaseItem().Interaction, Session, NextItem, 0);

                        }
                    } else {
                        Robot.AI.IsMoving = false;
                    }
                }
            }
        }
    }

    public boolean add(Robot Robot) {
        this.Robots.put(Robot.ID, Robot);

        return true;
    }

    public int count() {
        return this.Robots.size();
    }

    public THashMap<Integer, Robot> getRobots() {
        return this.Robots;
    }
}
