/*
Copyright (C) 2005 David Green <green@couchpotato.net>
All Rights Reserved.

This file is part of Aelfengard.

Aelfengard is proprietary software. You may not redistribute it without
prior written permission from the copyright holder.
*/
package server;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import common.CommonUtils;

public class HateList implements Externalizable {

    private static final long serialVersionUID = 1L;
    
    private static final long PLAYER_HATE_EXPIRATION = 3 * 60 * 1000; // 3 minutes
    private static final long NPC_HATE_EXPIRATION = 12 * 60 * 60 * 1000; // 12 hours
    
    private boolean isPlayer;
    private Map<Integer,Long> hateMap = new HashMap<Integer,Long>();
    private Set<Integer> hateSet = new HashSet<Integer>();
    
    public HateList() {
        /* for deserialization */
    }
    
    public HateList(boolean isPlayer) {
        this.isPlayer = isPlayer;
    }
    
    public void addHate(Living living) {
        if (living == null) {
            throw new NullPointerException();
        }
        hateSet.add(living.getId());
    }
    
    public void clearHate(Living living) {
        hateSet.remove(living.getId());
        hateMap.remove(living.getId());
    }
    
    public boolean isHated(Living living) {
        if (hateSet.contains(living.getId())) {
            return true;
        }
        Long expiration = hateMap.get(living.getId());
        if (expiration == null) {
            return false;
        }
        return expiration > System.currentTimeMillis(); // not expired yet
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(3); // protocol version
        out.writeBoolean(isPlayer);
        long time = System.currentTimeMillis();
        long newExpTime = time + (isPlayer ? PLAYER_HATE_EXPIRATION : NPC_HATE_EXPIRATION);
        for (Integer id : hateSet) {
            hateMap.put(id, newExpTime);
        }
        hateSet = new HashSet<Integer>();
        // TODO: Do this somewhere else
        Iterator<Map.Entry<Integer,Long>> iter = hateMap.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<Integer,Long> entry = iter.next();
            if (entry.getValue() < time) {
                iter.remove(); // hate expired
            }
        }
        out.writeObject(hateMap);
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        in.readInt(); // protocol version
        isPlayer = in.readBoolean();
        hateMap = CommonUtils.uncheckedCast(in.readObject());
    }

}