-- 
-- Please see the readme.txt file included with this distribution for 
-- attribution and copyright information.
--

forceactive = false;
forcedefensive = false;
forceeffects = false;
defensiveon = false;
activeon = false;
effectson = false;

function onInit()
	-- Initialization
	setDefensiveVisible(false);
	setActiveVisible(false);
	setEffectsVisible(false);
	
	-- Acquire token reference, if any
	linkToken();
	
	-- Set up the PC links
	if type.getValue() == "pc" then
		linkPCFields();
	end
	
	-- Update the status field
	status.updateStatus();

	-- Register the deletion menu item for the host
	registerMenuItem("Delete Item", "delete", 6);
end

function onClose()
	-- Close down the observers
	for k, v in ipairs(observers) do
		v.observedClosed(self);
	end
end

function linkToken()
	if tokenrefid and tokenrefnode then
		local imageinstance = token.populateFromImageNode(tokenrefnode.getValue(), tokenrefid.getValue());
		if imageinstance then
			token.acquireReference(imageinstance);
		end
	end
end

function onMenuSelection(selection)
	if selection == 6 then
		delete();
	end
end

function delete()
	-- Move to the next actor, if this CT entry is active
	if isActive() then
		windowlist.nextActor();
	end

	-- If this is an NPC with a token on the map, then remove the token also
	if type.getValue() == "npc" then
		token.deleteReference();
	end

	-- Clear the effects list
	effects.reset(false);

	-- Delete the database node and close the window
	getDatabaseNode().delete();

	-- Update the global subsection toggle buttons
	windowlist.onEntrySectionToggle();
end

function onTypeChanged()
	-- If a PC, then set up the links to the char sheet
	local val = type.getValue();
	if val == "pc" then
		linkPCFields();
	end

	-- If a NPC, then show the NPC display button; otherwise, hide it
	if val == "npc" then
		show_npc.setVisible(true);
	else
		show_npc.setVisible(false);
	end
end

function onWoundsChanged()
	-- Calculate the percent wounded for this unit
	local percent_wounded = 0;
	if hp.getValue() > 0 then
		percent_wounded = wounds.getValue() / hp.getValue();
	end
	
	-- Based on the percent wounded, change the font color for the Wounds field
	if percent_wounded <= 0 then
		wounds.setFont("ct_healthy_font");
	elseif percent_wounded <= .33 then
		wounds.setFont("ct_ltwound_font");
	elseif percent_wounded <= .66 then
		wounds.setFont("ct_modwound_font");
	elseif percent_wounded <= 1 then
		wounds.setFont("ct_hvywound_font");
	else
		wounds.setFont("ct_dead_font");
	end

	-- Based on the percent wounded, set the Status text field
	if percent_wounded <= 0 then
		status.setValue("Healthy");
	elseif percent_wounded <= .33 then
		status.setValue("Light");
	elseif percent_wounded <= .66 then
		status.setValue("Moderate");
	elseif percent_wounded < 1 then
		status.setValue("Heavy");
	elseif percent_wounded == 1 then
		status.setValue("Disabled");
	else
		if (wounds.getValue() - hp.getValue()) < 10 then
			status.setValue("Dying");
		else
			status.setValue("Dead");
		end
	end

	-- Update the token underlay to reflect wound status
	token.updateUnderlay();
end

function linkPCFields(src)
	local src = link.getTargetDatabaseNode();
	if src then
		name.setLink(src.getChild("name"), true);

		hp.setLink(src.getChild("hp.total"));
		wounds.setLink(src.getChild("hp.wounds"));
		
		ac.setLink(src.getChild("ac.totals.general"), src.getChild("ac.totals.touch"), src.getChild("ac.totals.flatfooted"));
		
		fortitudesave.setLink(src.getChild("saves.fortitude.total"), true);
		reflexsave.setLink(src.getChild("saves.reflex.total"), true);
		willsave.setLink(src.getChild("saves.will.total"), true);

		init.setLink(src.getChild("initiative.total"), true);
	end
end

function onFOFChanged()
	-- Update the token underlay to friend-or-foe status
	token.updateUnderlay();
end

-- Section visibility handling
function setSpacerState()
	if defensiveon or activeon or effectson then
		spacer.setVisible(true);
	else
		spacer.setVisible(false);
	end
end

function setDefensiveVisible(status)
	if activatedefensive.getValue() then
		status = true;
	end
	if not targeting.isEmpty() then
		status = true;
	end
	
	defensiveon = status;

	ac.setVisible(status);
	aclabel.setVisible(status);
	fortitudesave.setVisible(status);
	fortitudesavelabel.setVisible(status);
	reflexsave.setVisible(status);
	reflexsavelabel.setVisible(status);
	willsave.setVisible(status);
	willsavelabel.setVisible(status);
	targeting.setVisible(status);
	defensiveicon.setVisible(status);
	
	setSpacerState();
end
	
function setActiveVisible(status)
	if activateactive.getValue() then
		status = true;
	end
	if active.getState() then
		status = true;
	end
	
	activeon = status;

	speed.setVisible(status);
	speedlabel.setVisible(status);
	init.setVisible(status);
	initlabel.setVisible(status);
	atk.setVisible(status);
	atklabel.setVisible(status);
	fullatk.setVisible(status);
	fullatklabel.setVisible(status);
	activeicon.setVisible(status);
	
	setSpacerState();
end

function setEffectsVisible(status)
	if activateeffects.getValue() then
		status = true;
	end
	
	effectson = status;
	
	effecticon.setVisible(status);
	effects.setVisible(status);
	
	setSpacerState();
	
	if status then
		effects.checkForEmpty();
	end
end

function toggleForceEffects()
	forceeffects = not forceeffects;
	
	if forceeffects then
		activateeffects.setColor("ffffffff");
	else
		activateeffects.setColor("7fffffff");
	end
end

function toggleForceActive()
	forceactive = not forceactive;
	
	if forceactive then
		activateactive.setColor("ffffffff");
	else
		activateactive.setColor("7fffffff");
	end
end

function toggleForceDefensive()
	forcedefensive = not forcedefensive;
	
	if forcedefensive then
		activatedefensive.setColor("ffffffff");
	else
		activatedefensive.setColor("7fffffff");
	end
end

-- Activity state

function isActive()
	return active.getState();
end

function setActive(state)
	active.setState(state);
	
	if state then
		-- Turn notification
		local msg = {font = "narratorfont", icon = "indicator_flag"};
		msg.text = "[TURN] " .. name.getValue();
		
		local affectedby = effects.getEffectListString();
		if (affectedby ~= "") then
			msg.text = msg.text .. " - Effects: " .. affectedby;
		end 

		if type.getValue() == "pc" then
			-- Player Turn notification
			ChatManager.deliverMessage(msg);
			
			-- Ring bell also, if option enabled
			if OptionsManager.isOption("RING", "on") then
				local usernode = link.getTargetDatabaseNode();
				if usernode then
					local ownerid = User.getIdentityOwner(usernode.getName());
					if ownerid then
						User.ringBell(ownerid);
					end
				end
			end
		else
			-- DM Turn notification
			if show_npc.getState() then
				ChatManager.deliverMessage(msg);
			else
				msg.font = "systemfont";
				msg.text = "[GM] " .. msg.text;
				ChatManager.addMessage(msg);
			end
		end
	end
end

-- Observers to support effects linked here

observers = {};

function addObserver(o)
	table.insert(observers, o);
end

function removeObserver(o)
	for i = 1, #observers do
		if observers[i] == o then
			table.remove(observers, i);
			break;
		end
	end
end

function nameChanged()
	for k, v in ipairs(observers) do
		v.observedNameChanged(self);
	end
end
