/**
 * Copyright © 2010, Res Interactive, LLC
 */
package com.tootsville.npc;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import org.starhope.appius.except.GameLogicException;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.except.PrivilegeRequiredException;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.game.DamageArea;
import org.starhope.appius.game.DamageTypeRanks;
import org.starhope.appius.room.Room;
import org.starhope.appius.room.RoomListener;
import org.starhope.appius.user.AbstractNonPlayerCharacter;
import org.starhope.appius.user.AbstractUser;
import org.starhope.appius.user.Nomenclator;
import org.starhope.appius.util.AppiusConfig;

import org.json.JSONObject;

/**
 * @author ewinkelman@resinteractive.com
 */
public class Stu extends AbstractNonPlayerCharacter {

    /**
     * Java serialisation unique ID
     */
    private static final long serialVersionUID = -1198018618268919892L;

    /**
     * Static next instance ID for keeping track of instances of soccer
     * balls
     */
    private static AtomicInteger nextInstanceID = new AtomicInteger ();

    /**
     * WRITEME: Document this brpocock@star-hope.org
     */
    private long lastCasualInvite = 0;

    /**
     * @throws NotFoundException WRITEME
     * @throws GameLogicException WRITEME
     */
    public Stu ()
    throws NotFoundException, GameLogicException {
        super ("Stu");
        setVariable ("noClick", "true");
        final DamageTypeRanks defense = new DamageTypeRanks ();
        defense.add (Nomenclator.getDataRecord (DamageArea.class,
                "Wish"), 100);
        defense.add (Nomenclator.getDataRecord (DamageArea.class,
                "Shadow"), 100);
        changeBaseDefenses (defense);
    }


    /**
     * @see org.starhope.appius.user.AbstractUser#acceptMessage(java.lang.String,
     *      java.lang.String, java.lang.String)
     */
    @Override
    public void acceptMessage (final String title, final String label,
            final String content) {
        // no op
    }

    /**
     * @see org.starhope.appius.room.RoomListener#acceptObjectJoinRoom(org.starhope.appius.room.Room,
     *      org.starhope.appius.room.RoomListener)
     */
    @Override
    public void acceptObjectJoinRoom (final Room room,
            final RoomListener object) {
        // no op
    }




    /**
     * @see org.starhope.appius.room.RoomListener#acceptObjectPartRoom(org.starhope.appius.room.Room, org.starhope.appius.room.RoomListener)
     */
    @Override
    public void acceptObjectPartRoom (final Room room,
            final RoomListener thing) {
        // TODO brpocock@star-hope.org Auto-generated method stub (Jul 30, 2010)

    }

    /**
     * @see org.starhope.appius.room.RoomListener#acceptOutOfBandMessage(org.starhope.appius.user.AbstractUser, org.starhope.appius.room.Room, org.json.JSONObject)
     */
    @Override
    public void acceptOutOfBandMessage (final AbstractUser sender,
            final Room room, final JSONObject body) {
    // no op
    }



    /**
     * @see org.starhope.appius.room.RoomListener#acceptPublicMessage(org.starhope.appius.user.AbstractUser,
     *      org.starhope.appius.room.Room, java.lang.String)
     */
    @Override
    public void acceptPublicMessage (final AbstractUser sender,
            final Room room, final String message) {
        if (getRoom ().equals (room)) {
            acceptPublicMessage (sender, message);
        }

    }

    /**
     * @see org.starhope.appius.room.RoomListener#acceptPublicMessage(org.starhope.appius.user.AbstractUser,
     *      java.lang.String)
     */
    @Override
    public void acceptPublicMessage (final AbstractUser from,
            final String message) {
        if (equals (from)) {
            return;
        }


        if ("/cry".equals (message)) {
            AppiusClaudiusCaecus.getKalendor ().schedule (
                    System.currentTimeMillis () + 4000,
                    new Runnable () {
                        /**
                         * @see java.lang.Runnable#run()
                         */
                        @Override
                        public void run () {
                            speak (getRoom (), "Don't cry, "
                                    + from.getAvatarLabel ()
                                    + " … It's only a game");
                        }
                    });
        }
        final Pattern greetings = Pattern.compile (
                "(?:hi|hello|welcome|yo|howdy|hola|hey|bonjour|bonsoir)?[, ]+Stu",
                Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
        if (greetings.matcher (message).matches ()) {
            AppiusClaudiusCaecus.getKalendor ().schedule (
                    System.currentTimeMillis () + 4000,
                    new Runnable () {
                        /**
                         * @see java.lang.Runnable#run()
                         */
                        @Override
                        public void run () {
                            speak (getRoom (), "Hi, "
                                    + from.getAvatarLabel () + "!");
                        }
                    });

            if (lastCasualInvite < System.currentTimeMillis () - 30000) {
                lastCasualInvite = System.currentTimeMillis ();

                AppiusClaudiusCaecus.getKalendor ().schedule (
                        System.currentTimeMillis () + 8000,
                        new Runnable () {
                            /**
                             * @see java.lang.Runnable#run()
                             */
                            @Override
                            public void run () {
                                // TODO: check if they're on field
                                speak (
                                        getRoom (),
                                        "Come play soccer with us, "
                                        + from
                                        .getAvatarLabel ());
                            }
                        });
            }
        }

        final Pattern iRobot = Pattern.compile (".*\\bstu\\b.*bot\\b",
                Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
        final Pattern robotI = Pattern.compile (".*bot\\b.*\\bstu\\b",
                Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
        if (iRobot.matcher (message).matches ()
                || robotI.matcher (message).matches ()) {
            AppiusClaudiusCaecus.getKalendor ().schedule (
                    System.currentTimeMillis () + 5300,
                    new Runnable () {
                        /**
                         * @see java.lang.Runnable#run()
                         */
                        @Override
                        public void run () {
                            final String [] phrases = {
                                    "Why does everyone think I'm a robot? I'm a Toot!",
                                    "I'm not a robot, silly. I'm a Toot!",
                                    "Is " + from.getAvatarLabel ()
                                    + " a robot?",
                                    "I thought "
                                    + from.getAvatarLabel ()
                                    + " was a robot, but I guess not.",
                                    "/frown", "Robot indeed. Ha.",
                            "The only robots in Tootsville are usually underground…" };
                            final String phrase = phrases [AppiusConfig
                                                           .getRandomInt (0, phrases.length)];
                            speak (getRoom (), phrase);
                        }
                    });
        }

    }



    /**
     * @see org.starhope.appius.user.AbstractUser#ban(org.starhope.appius.user.AbstractUser,
     *      java.lang.String)
     */
    @Override
    public void ban (final AbstractUser u, final String banReason)
    throws PrivilegeRequiredException {
        destroy ();
    }

    /**
     * Gets the NPC's instance ID
     *
     * @see org.starhope.appius.user.AbstractNonPlayerCharacter#getInstanceID()
     */
    @Override
    protected int getInstanceID () {
        return Stu.nextInstanceID.incrementAndGet ();
    }



}
