------------------------------------------------------------------------------------------
--			Nurfed Utility Functions
------------------------------------------------------------------------------------------

if (not Nurfed_Utility) then
	Nurfed_Utility = {};
	Nurfed_Utility.hooked = {};
	
	function Nurfed_Utility:New()
		local object = {};
		setmetatable(object, self);
		self.__index = self;
		return object;
	end
	
	function Nurfed_Utility:Print (msg, out, r, g, b, a)
		if (not msg) then	msg = "nil";			end
		if (not out) then	out = 1;				end
		if (not r) then		r = 1.0;				end
		if (not g) then		g = 1.0;				end
		if (not b) then		b = 1.0;				end
		if (not a) then		a = 1.0;				end
	
		if (out == "e" or out == "err" or out == "error") then
			UIErrorsFrame:AddMessage(msg, r, g, b, a, UIERRORS_HOLD_TIME);
		else
			local frame = getglobal("ChatFrame"..out);
			if (frame) then
				frame:AddMessage(msg, r, g, b);
			else
				DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b);
			end
		end
	end
	
	function Nurfed_Utility:Hook (mode, original, new)
		if (not mode) then
			mode = "after";
		end
		
		if (self.hooked[original]) then
			return;
		end

		self.hooked[original] = getglobal(original);

		if (mode == "before") then
			setglobal(original, function (...)
				new(unpack(arg));
				self.hooked[original](unpack(arg));
			end);
		elseif (mode == "after") then
			setglobal(original, function (...)
				self.hooked[original](unpack(arg));
				new(unpack(arg));
			end);
		elseif (mode == "replace") then
			setglobal(original, function (...)
				new(unpack(arg));
			end);
		end
	end
	
	function Nurfed_Utility:UnHook (original)
		if (self.hooked[original]) then
			setglobal(original, self.hooked[original]);
			self.hooked[original] = nil;
		end
	end
	
	function Nurfed_Utility:GetQuadrant (frame)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		local quadrant;
		
		local frameX, frameY = frame:GetCenter();
	
		local screenX, screenY = UIParent:GetCenter();
		
		if (frameX > screenX) then
			quadrant = "RIGHT";
		else
			quadrant = "LEFT";
		end
		
		if (frameY > screenY) then
			quadrant = "TOP"..quadrant;
		else
			quadrant = "BOTTOM"..quadrant;
		end
		
		return quadrant;
	end
	
	function Nurfed_Utility:GetHalf (frame, orientation)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		local frameX, frameY = frame:GetCenter();
		
		local screenX, screenY = UIParent:GetCenter();
		
		if (orientation == "HORI") then
			if (frameX > screenX) then
				return "RIGHT";
			else
				return "LEFT";
			end
		else
			if (frameY > screenY) then
				return "TOP";
			else
				return "BOTTOM";
			end
		end
	end
	
	function Nurfed_Utility:GetOppositePoint (point)
		if (not point or point == "CENTER") then
			point = "CENTER";
		else
			if (strfind(point, "TOP")) then
				point = gsub(point, "TOP", "BOTTOM");
			else
				point = gsub(point, "BOTTOM", "TOP");
			end

			if (strfind(point, "LEFT")) then
				point = gsub(point, "LEFT", "RIGHT");
			else
				point = gsub(point, "RIGHT", "LEFT");
			end
		end
		
		return point;
	end
	
	function Nurfed_Utility:GetAnchors (frame, directional, orientation)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		local point;
			
		if (directional) then
			point = self:GetHalf(frame, orientation);
		else
			point = self:GetQuadrant(frame);			
		end
		
		return point, frame:GetName(), self:GetOppositePoint(point);
	end
	
	function Nurfed_Utility:PositionTooltip (frame)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		GameTooltip:SetOwner(frame);
		
		GameTooltip:ClearAllPoints();
		GameTooltip:SetPoint(self:GetAnchors(frame));
	end
	
	function Nurfed_Utility:GetCursorOffsets (frame)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		local screenX, screenY = UIParent:GetCenter();
		local offsetX, offsetY = GetCursorPosition();
		offsetX = offsetX / UIParent:GetScale();
		offsetY = offsetY / UIParent:GetScale();

		if (screenX < offsetX) then
			offsetX = offsetX - frame:GetWidth();
		end
		
		if (screenY < offsetY) then
			offsetY = offsetY - frame:GetHeight();
		end
		
		return offsetX, offsetY;
	end
	
	function Nurfed_Utility:PositionDropDown (frame)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return nil;
		end
		
		if (frame == "cursor") then
			DropDownList1:ClearAllPoints();
			DropDownList1:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", self:GetCursorOffsets(DropDownList1));
		else
			DropDownList1:ClearAllPoints();
			DropDownList1:SetPoint(self:GetAnchors(frame));
		end
		
		if (DropDownList2:IsVisible()) then
			DropDownList2:ClearAllPoints();
			DropDownList2:SetPoint(self:GetAnchors(DropDownList1, 1, "HORI"));
			
			if (DropDownList3:IsVisible()) then
				DropDownList3:ClearAllPoints();
				DropDownList3:SetPoint(self:GetAnchors(DropDownList2, 1, "HORI"));
			end
		end
	end

	function Nurfed_Utility:TableCopy(t)
		local new = {};
		local i, v = next(t, nil);
		while i do
		if type(v)=="table" then 
			v=self:TableCopy(v);
		end 
		new[i] = v;
		i, v = next(t, i);
		end
		return new;
	end

	function Nurfed_Utility:ValidatePosition(frame)
		if (this and not frame) then
			frame = this;
		elseif (not frame) then
			return;
		end

		if (not frame:GetRight() or not frame:IsMovable()) then
			return;
		end

		local frameLeft = frame:GetLeft();
		local frameRight = frame:GetRight() * frame:GetEffectiveScale();
		local frameTop = frame:GetTop() * frame:GetEffectiveScale();
		local frameBottom = frame:GetBottom();
		local screenLeft = UIParent:GetLeft();
		local screenRight = UIParent:GetRight();
		local screenTop = UIParent:GetTop();
		local screenBottom = UIParent:GetBottom();

		local adjustment = 3;

		local x = frameLeft;
		local y = frameBottom;

		if (screenTop < frameTop) then
			y = screenTop + adjustment;
		elseif (screenBottom > frameBottom) then
			y = screenBottom - adjustment;
		end
		
		if (screenLeft > frameLeft) then
			x = screenLeft - adjustment;
		elseif (screenRight < frameRight) then
			x = screenRight - adjustment;
		end
		
		if (x == 0) then
			x = 1 - adjustment;
		end
		
		if (y == screenTop - frame:GetHeight()) then
			y = y - 1 + adjustment;
		end
		
		if (x == frameLeft and y == frameBottom) then
			return;
		end

		frame:ClearAllPoints();
		frame:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", x, y);
		frame:SetUserPlaced(1);
	end

	function Nurfed_Utility:AddLockFunc(func)
		if (func) then
			table.insert(Nurfed_LockFuncs, func)
		end
	end
end