# petFeeder v1.5
# -by punkpudding

package petFeeder;

use strict;
use Time::HiRes qw(time);
use Globals;
use Plugins;
use Log qw(debug message warning error);
use Utils;
use Commands;
use Network;
use Network::Send;

Plugins::register('petFeeder', 'petFeeder by punkpudding', \&onUnload, \&onReload);
my $hookCommandPost = Plugins::addHook('Command_post', \&onCommandPost);
my $hookAIpre = Plugins::addHook('AI_pre', \&onAIpre);
my $hookParseMsgPre = Plugins::addHook('parseMsg/pre', \&onParseMsgPre);

message "Pet feeding plugin loaded\n", "success";

my %pet;
my $hunger = 72;
my $performanceRate = $config{petPerformanceRate};


sub onUnload {
	Plugins::delHook('parseMsg/pre', $hookParseMsgPre);
	Plugins::delHook('AI_pre', $hookAIpre);
	Plugins::delHook('Command_post', $hookCommandPost);
	message "Pet feeding plugin unloaded\n", "success";
}

sub onReload {
	&onUnload;
}

sub onCommandPost {
	my (undef, $args) = @_;
	my ($cmd, $subcmd) = split(' ', $args->{input}, 2);
	if ($cmd eq "pet" && $config{petFeeder}) {
		if ($subcmd eq "s" || $subcmd eq "status") {
			message "Pet status: hungry=$pet{hungry} intimacy=$pet{friendly}\n";
		} elsif ($subcmd eq "f" || $subcmd eq "feed") {
			if ($pet{hungry} <= 72) {
				message "Feeding your pet. [current intimacy : $pet{friendly}]\n";
				sendPetFeed($::net);
				sendPetGetInfo($::net);
			} elsif ($pet{hungry} > 72) {
				message "Your pet's not yet hungry. Feeding him now will lower intimacy.\n";
			}
		} elsif ($subcmd eq "p" || $subcmd eq "performance") {
			message "Playing your pet.\n";
			sendPetPerformance($::net);
		} elsif ($subcmd eq "r" || $subcmd eq "return") {
			message "Returning pet to egg status.\n";
			sendPetReturnToEgg($::net);
		} elsif ($subcmd eq "u" || $subcmd eq "unequip") {
			message "Unequipping pet accessory.\n";
			sendPetUnequipItem($::net);
		} else {
			error "Syntax Error in function 'pet' (pet management)\n" .
				"Usage: pet < s[tatus] | f[eed] | p[erformance] | r[eturn] | u[nequip] >\n";
		}
		$args->{return} = 1;
	}
}

sub onAIpre {
	return unless ($main::conState == 5);
	if ($config{petFeeder}) {
		# request status
		if (timeOut($pet{lastStatusInfo}, 30)) {
			if (timeOut($pet{lastStatusRequest}, 10)) {
				$pet{lastStatusRequest} = time;
				sendPetGetInfo($::net);
				if ($pet{friendly} < 990) { $hunger = 72; }
				elsif ($pet{friendly} >=990) { $hunger = 30; }
			}
		}
		# pet performance
		if ((defined($config{petPerformanceRate}) && timeOut($pet{lastPerformance}, $performanceRate))
		  && ((!$config{petPerformance_onAction}) || ($config{petPerformance_onAction} && existsInList($config{petPerformance_notOnAction}, AI::action())))
		  && ((!$config{petPerformance_notOnAction}) || ($config{petPerformance_notOnAction} && !existsInList($config{petPerformance_notOnAction}, AI::action())))
		) {
			sendPetPerformance($::net);
			message "Auto-playing your pet\n";
			$performanceRate = $config{petPerformanceRate} if !defined($performanceRate);
			$performanceRate = $config{petPerformanceRate} + int(rand $config{petPerformanceRateSeed}) if $config{petPerformanceRateSeed};
			$pet{lastPerformance} = time;
		}
	}
}

sub onParseMsgPre {
	my (undef, $args) = @_;
	my $switch = $args->{switch};
	my $msg = $args->{msg};
	# process status
	if ($switch eq "01A2" && $config{petFeeder}) {
		$pet{name} = substr($msg, 2, 24) =~ /([\s\S]*?)\000/;
		$pet{nameflag} = unpack("C1", substr($msg, 26, 1));
		$pet{level} = unpack("S1", substr($msg, 27, 2));
		$pet{hungry} = unpack("S1", substr($msg, 29, 2));
		$pet{friendly} = unpack("S1", substr($msg, 31, 2));
		$pet{accessory} = unpack("S1", substr($msg, 33, 2));
		$pet{lastStatusInfo} = time;
		debug "Pet status: level=$pet{level} hungry=$pet{hungry} intimacy=$pet{friendly}\n";
		if ($config{petSmartFeed}) {
			if ($pet{hungry} < $hunger && timeOut($pet{lastFeed}, 5) && $pet{friendly} > 0) {
				$pet{lastFeed} = time;
				sendPetFeed($::net);
				sendPetGetInfo($::net);
				message "Auto-feeding your pet. [current intimacy : $pet{friendly}]\n";
			}
			if ($pet{hungry} <= $config{petMinHunger} || $pet{hungry} <= 15) {
				sendPetReturnToEgg($::net);
				message "Critical hunger level reached. Pet returned to egg status.\n";
			}	
		} else {
			if ($pet{hungry} < $config{petFeedRate} && timeOut($pet{lastFeed}, 5) && $pet{friendly} > 0) {
				$pet{lastFeed} = time;
				sendPetFeed($::net);
				sendPetGetInfo($::net);
				message "Auto-feeding your pet. [current intimacy : $pet{friendly}]\n";
			}
			if ($pet{hungry} <= $config{petMinHunger} || $pet{hungry} <= 15) {
				sendPetReturnToEgg($::net);
				message "Critical hunger level reached. Pet returned to egg status.\n";
			}	
		}
	}
}

return 1;