package de.iani.cubequest.interaction;

import de.iani.cubequest.CubeQuest;
import de.iani.cubequest.ServerSpecific;
import java.sql.SQLException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;

public abstract class Interactor
        implements ServerSpecific, Comparable<Interactor>, ConfigurationSerializable {
    
    public static final Comparator<Interactor> COMPARATOR = (i1, i2) -> {
        if (i1 == null) {
            return i2 == null ? 0 : -1;
        } else {
            return i2 == null ? 1 : i1.compareTo(i2);
        }
    };
    
    private int serverId;
    private String cachedName;
    
    public Interactor() {
        this.serverId = CubeQuest.getInstance().getServerId();
    }
    
    public Interactor(int serverId) {
        this.serverId = serverId;
    }
    
    public Interactor(Map<String, Object> serialized) {
        this.serverId = (Integer) serialized.get("serverId");
        this.cachedName = (String) serialized.get("cachedName");
    }
    
    public abstract Object getIdentifier();
    
    public String getName() {
        return getName(false);
    }
    
    public String getName(boolean ignoreCache) {
        String name = getAndCacheName();
        
        if (name != null) {
            this.cachedName = name;
            return name;
        }
        
        if (ignoreCache) {
            return null;
        }
        
        return this.cachedName;
    }
    
    protected abstract String getAndCacheName();
    
    @Override
    public boolean isForThisServer() {
        return CubeQuest.getInstance().getServerId() == this.serverId;
    }
    
    public int getServerId() {
        return this.serverId;
    }
    
    public String getServerName() {
        try {
            return (isForThisServer() ? CubeQuest.getInstance().getBungeeServerName()
                    : CubeQuest.getInstance().getDatabaseFassade().getServerName(this.serverId));
        } catch (SQLException e) {
            CubeQuest.getInstance().getLogger().log(Level.SEVERE,
                    "Could not load server name for server with id " + this.serverId, e);
            return null;
        }
    }
    
    public void changeServerToThis() {
        this.serverId = CubeQuest.getInstance().getServerId();
    }
    
    public void makeAccessible() {
        
    }
    
    public void resetAccessible() {
        
    }
    
    public abstract boolean isLegal();
    
    public abstract String getInfo();
    
    public Location getLocation() {
        return getLocation(false);
    }
    
    public abstract Location getLocation(boolean ignoreCache);
    
    public abstract double getHeight();
    
    public abstract double getWidth();
    
    @Override
    public Map<String, Object> serialize() {
        Map<String, Object> result = new HashMap<>();
        result.put("serverId", this.serverId);
        result.put("cachedName", this.cachedName);
        return result;
    }
    
    @Override
    public int compareTo(Interactor o) {
        int result = this.getClass().getName().compareTo(o.getClass().getName());
        return result != 0 ? result : this.serverId - o.serverId;
    }
    
    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Interactor)) {
            return false;
        }
        Interactor interact = (Interactor) other;
        
        return this.serverId == interact.serverId
                && getIdentifier().equals(interact.getIdentifier());
    }
    
    @Override
    public int hashCode() {
        return (31 * this.serverId) + getIdentifier().hashCode();
    }
    
}

@@ -3507,24 +3507,91 @@
 t other) %7B%0D%0A
+        if (other == this) %7B%0D%0A            return true;%0D%0A        %7D%0D%0A
         if (
@@ -3724,39 +3724,36 @@
       %0D%0A        
-return 
+if (
 this.serverId ==
@@ -3750,17 +3750,17 @@
 erverId 
-=
+!
 = intera
@@ -3770,16 +3770,19 @@
 serverId
+) %7B
 %0D%0A      
@@ -3791,15 +3791,47 @@
     
-    && 
+return false;%0D%0A        %7D%0D%0A        if (!
 getI
@@ -3874,16 +3874,271 @@
 ifier())
+) %7B%0D%0A            return false;%0D%0A        %7D%0D%0A        if (getClass() == other.getClass()) %7B%0D%0A            return true;%0D%0A        %7D%0D%0A        %0D%0A        return InteractorType.fromClass(getClass()) == InteractorType%0D%0A                .fromClass(interact.getClass())
 ;%0D%0A    %7D

Improve Interactor#equals()