
BWP_NAME = "MetaMapBWP";
BWP_IMAGE_PATH = "Interface\\AddOns\\MetaMapBWP\\Artwork\\Arrows\\"
BWP_BUTTON_HEIGHT = 16;
BWP_BUTTON_COUNT = 11;

BWP_Options = {};
BWP_Data = {};
BWP_CZone = {};
BWP_Destination = nil;
BWP_Data["Kalimdor"] = {};
BWP_Data["Eastern Kingdoms"] = {};

local BWPnode = {};
local BWPmeta = {};
local BWPDisp = {};
local BWPDispm = {};

BWP_CountDown = 0;
BWP_SetDist = 0;
BWP_ArrowIcon = nil;
BWP_playerIsDead = false;
BWP_GuardActive = false;

BWP_Highlighttext ="|cffFFFFFF";
BWP_Redtext="|cffFF0000";
BWP_Greentext = "|cff00FF00";

local BWP_Zones = {};
local BWP_KalimdorZones = {};
local BWP_EasternZones = {};
local BWP_Player = nil;
local BWP_SetSpecial = false;
local BWP_SpecialDest = 0;
local old_ToggleDropDownMenu = ToggleDropDownMenu;
local Old_AbandonQuest =  AbandonQuest
oldBWPFOLLOW_UnitPopup_OnClick = UnitPopup_OnClick
-- Query redirect
BWPDispm.__index = SNDisp;
-- Query redirect
BWPmeta.__index = BWPnode;
local BWP_FirstLoad = true;
local gdpx, gdpy, gddx, gddy, gddir, gdclx, gdcly;
--Map Variables below
local MAX_LOC_SAMPLES = 50;-- Circular arrays to store X,Y,time locations
local LOC_X_SAMPLES = {};
local LOC_Y_SAMPLES = {};
local LOC_T_SAMPLES = {};	
-- The last index written into
local lastIdx = 0;
-- Last coordinates, used to avoid spamming location arrays
local lastX,lastY = 0,0;
-- Configuration/thresholds -- Tune these together with coordinate
-- system for a balance of update speed and jitter reduction
-- Make sure that MIN_CUMUL_RANGE is at least 2 times as large as	
-- MIN_SAMPLE_DISTANCE (Preferably between about 3-10 times)
-- Minimum change in at least one direction to store something	
local MIN_SAMPLE_DISTANCE = 0.0001;
-- Maximum age of an old record to look at
local MAX_CUMUL_TIME = 2.0;
-- Minimum range for a significant vector
local MIN_CUMUL_RANGE = 0.0003;
-- Square of minimum range to avoid an unnecessary sqrt
local MIN_CUMUL_RANGE_SQ = MIN_CUMUL_RANGE * MIN_CUMUL_RANGE;
-- Last degree value, just here for debugging sanity
local lastDeg = nil;

function BWP_SetVars()
	if(BWP_Options.ShowYards == nil) then BWP_Options.ShowYards = false; end
	if(BWP_Options.ShowCorpse == nil) then BWP_Options.ShowCorpse = false; end
	if(BWP_Options.ShowOnGuard == nil) then BWP_Options.ShowOnGuard = false; end
	if(BWP_Options.SetAlpha == nil) then BWP_Options.SetAlpha = 1.0; end
	if(BWP_Options.SetDistance == nil) then BWP_Options.SetDistance = 0.0040; end
	if(BWP_Options.ShowPoints == nil) then BWP_Options.ShowPoints = true; end
	if(BWP_Options.ShowNPC == nil) then BWP_Options.ShowNPC = true; end
	if(BWP_Options.ClearDest == nil) then BWP_Options.ClearDest = true; end
end

function BWP_OnLoad()
	SLASH_BWPCOMMAND1 = "/bwp"; 
	SlashCmdList["BWPCOMMAND"] = BWP_LocCommand
	this:RegisterEvent("ADDON_LOADED");
	this:RegisterEvent("WORLD_MAP_UPDATE");
	this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
	this:RegisterEvent("CHAT_MSG_SYSTEM");
	this:RegisterEvent("QUEST_GREETING");
	this:RegisterEvent("UNIT_NAME_UPDATE");
	this:RegisterEvent("QUEST_COMPLETE");
	this:RegisterEvent("QUEST_FINISHED");
	this:RegisterEvent("QUEST_GREETING");
	this:RegisterEvent("QUEST_ACCEPT_CONFIRM");
	this:RegisterEvent("GOSSIP_CLOSED");
	this:RegisterEvent("PLAYER_DEAD");
	table.insert(UnitPopupMenus["PLAYER"],"BWPFOLLOW")
	table.insert(UnitPopupMenus["PARTY"],"BWPFOLLOW")
	table.insert(UnitPopupMenus["RAID"],"BWPFOLLOW")
	UnitPopupButtons["BWPFOLLOW"] = { text = "Set As Waypoint", dist = 0 } 
end

function BWP_OnEvent(event)
	if(event == "ADDON_LOADED") then
		BWP_SetVars()
		BWP_OptionsInit();
		BWP_Generate()
		MetaKBMenu_RBSelect = BWP_ShowKBMenu;
		MetaMapNotes_RBSelect = BWP_ShowNoteMenu;
	end
	if(event == "ZONE_CHANGED_NEW_AREA" or event == "PLAYER_ENTERING_WORLD") then
		BWP_OptionsInit();
	end
	if (event == "UNIT_NAME_UPDATE" and arg1 == "player") then 
		if (BWP_FirstLoad) then
			BWP_Player = UnitName("player");
			if (playerName ~= UNKNOWNOBJECT) then 
				BWP_FirstLoad = nil;
			end
		end
	end
	if(event == "GOSSIP_CLOSED") then
		BWP_SetSpecial = true;
		BWP_SpecialDest = 2;
	end
	if(event == "QUEST_COMPLETE") then
		local title = GetTitleText() or "";
		clearquest(title)
	end
	if(strsub(event,1,16) == "CHAT_MSG_SYSTEM") then
		local msg = arg1;
		local plr = arg2;
		if ( (msg and msg ~= nil) and (plr and plr ~= nil) ) then
			local _,_,questname = string.find(msg,"Quest accepted: (.*)")
			if(questname) then
				BWP_AddQuest(questname)
			end						
		end
	end
end

function BWP_OnUpdate(arg)
	if(UnitIsDeadOrGhost("player")) then
		DeadMan();
	else
		BWP_Alive();
	end
	if(BWP_SetSpecial) then BWP_Special_Dest(); end

	if(BWP_CountDown > 0) then 
		BWP_CountDown = BWP_CountDown - 1; 
		if(BWP_CountDown == 1 and BWP_Options.ClearDest) then
			BWP_CountDown = 0;
			if(BWP_SpecialDest) then
				BWP_SpecialOff();
			else
				BWP_ClearDest();
			end
		end
		return;
	end
	if(BWP_Destination) then
		local UpdateBWP = BWP_GetDir();
		if(UpdateBWP) then BWP_SetRotation(UpdateBWP); end
		BWPDistanceText:SetText(BWP_GetDistText())
	end
end

function  BWP_LocCommand(msg)
	local name = "QuickLoc";
	local i,j,x,y,tmp = string.find(msg,"%s*(%d+)%s*[,.]%s*(%d+)%s*([^%c]*)");
	if(x == nil or y == nil) then
		SetMapToCurrentZone();
		x, y = GetPlayerMapPosition("player");
		if(msg ~= "" and msg ~= nil) then
			name = msg;
		end
	else
		x = x / 100;
		y = y / 100;
		if(tmp ~= "" and tmp ~= nil) then
			name = tmp;
		end
	end
	setmininote(x, y, name, 7);
	BWP_OptionsInit();
end

function BWP_SelectionDropDown_OnLoad()
	UIDropDownMenu_Initialize(BWP_OptionsDropDown, BWP_DropDownFrame_Initialize );
	UIDropDownMenu_SetWidth(80);
end

function ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset)
	if(this:GetParent()) and (this:GetParent():GetName())and(this:GetParent():GetName()== "BWP_MenuFrame_DropDown")then
		BWP_MenuFrame:Show();
		old_ToggleDropDownMenu(level, value, dropDownFrame,"BWP_MenuFrame", xOffset, yOffset)
	else
		old_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset)
		BWP_MenuFrame:Hide();
	end
	return nil
end

function BWP_OptionsInit()
	if(BWP_Options.SetAlpha < 0.15) then BWP_Options.SetAlpha = 0.15; end
	BWP_DistanceSlider:SetValue(BWP_Options.SetDistance);
	BWP_AlphaSlider:SetValue(BWP_Options.SetAlpha);
	if(BWP_Destination and BWP_Destination.zone == GetRealZoneText()) then
		BWPDestText:SetText("("..BWP_Destination.name..")");
		BWPDistanceText:SetText(BWP_GetDistText())
		BWP_DisplayFrame:Show();
	else
		BWP_DisplayFrame:Hide();
	end
end

function MetaMapBWP_UpdateDistance()
	BWP_Options.SetDistance = this:GetValue();
	local dist = MetaMap_round(this:GetValue() * 4000)
	BWP_SetDistText:SetText(dist);
end

function MetaMapBWP_UpdateAlpha()
	BWP_Options.SetAlpha = this:GetValue();
	BWP_DisplayFrame:SetAlpha(BWP_Options.SetAlpha);
end

function MetaMapBWPMenu_Init()
	local items = 0;
	for i=1, BWP_BUTTON_COUNT, 1 do
		local button = getglobal("MetaMapBWPMenu_Option"..i);
		button:SetHeight(BWP_BUTTON_HEIGHT);
		if(i == 1) then
			button:SetText("Always load on startup");
			button.toggle = MetaMapOptions.BWPalwaysOn;
		elseif(i == 2) then
			button:SetText(BWP_SHOW_CORPSE);
			button.toggle = BWP_Options.ShowCorpse;
		elseif(i == 3) then
			button:SetText(BWP_SHOW_GUARD);
			button.toggle = BWP_Options.ShowOnGuard;
		elseif(i == 4) then
			button:SetText(BWP_SHOW_QNPC);
			button.toggle = BWP_Options.ShowNPC;
		elseif(i == 5) then
			button:SetText(BWP_SHOW_MAPPOINTS);
			button.toggle = BWP_Options.ShowPoints;
		elseif(i == 6) then
			button:SetText(BWP_CLEAR_ARRIVE);
			button.toggle = BWP_Options.ClearDest;
		elseif(i == 7) then
			if(BWP_Options.ShowYards) then
				button:SetText(BWP_SHOW_METRES);
			else
				button:SetText(BWP_SHOW_YARDS);
			end
			button.toggle = false;
		elseif(i == 8) then
			button:SetHeight(10); -- Spacer
		elseif(i == 9) then
			button:SetText(BWP_CLEAR_DEST);
			button.toggle = false;
		elseif(i == 10) then
			button:SetHeight(0); -- Spare
			button.toggle = false;
		elseif(i == 11) then
			button:SetHeight(0); -- Spare
			button.toggle = false;
		end
		if(button.toggle) then
			getglobal("MetaMapBWPMenu_Option"..i.."Check"):Show();
		else
			getglobal("MetaMapBWPMenu_Option"..i.."Check"):Hide();
		end
		button:Show();
		items = i;
	end
	MetaMapBWPMenu:ClearAllPoints();
	local yPos = "TOP";
	local xPos = "RIGHT";
	local x, y = GetCursorPosition();
	x = x / UIParent:GetEffectiveScale() +15;
	y = y / UIParent:GetEffectiveScale() +15;
	if(y <= (UIParent:GetHeight() /2)) then yPos = "BOTTOM"; y = y +50; end
	if(x <= (UIParent:GetHeight() /2)) then xPos = "LEFT"; x = x -30; end
	MetaMapBWPMenu:SetPoint(yPos..xPos, "UIParent", "BOTTOMLEFT", x, y);
	MetaMapBWPMenu:SetHeight((BWP_BUTTON_HEIGHT *items) + (BWP_BUTTON_HEIGHT *2));
	PlaySound("UChatScrollButton");
	MetaMapBWPMenu:Show();
end

function MetaMapBWPMenu_Select(id)
	local button = getglobal("MetaMapBWPMenu_Option"..id);
	if(id == 1) then
		MetaMapOptions.BWPalwaysOn = not MetaMapOptions.BWPalwaysOn;
		button.toggle = MetaMapOptions.BWPalwaysOn;
	elseif(id == 2) then
		BWP_Options.ShowCorpse = not BWP_Options.ShowCorpse;
		button.toggle = BWP_Options.ShowCorpse;
	elseif(id == 3) then
		BWP_Options.ShowOnGuard = not BWP_Options.ShowOnGuard;
		button.toggle = BWP_Options.ShowOnGuard;
	elseif(id == 4) then
		BWP_Options.ShowNPC = not BWP_Options.ShowNPC;
		button.toggle = BWP_Options.ShowNPC;
	elseif(id == 5) then
		BWP_Options.ShowPoints = not BWP_Options.ShowPoints;
	elseif(id == 6) then
		BWP_Options.ClearDest = not BWP_Options.ClearDest;
		button.toggle = BWP_Options.ClearDest;
	elseif(id == 7) then
		BWP_Options.ShowYards = not BWP_Options.ShowYards;
		if(BWP_Options.ShowYards) then
			button:SetText(BWP_SHOW_METRES);
		else
			button:SetText(BWP_SHOW_YARDS);
		end
		button.toggle = false;
	elseif(id == 8) then
		-- Spacer
	elseif(id == 9) then
		BWP_ClearDest();
		button.toggle = false;
	elseif(id == 10) then
		-- spare
	elseif(id == 11) then
		-- spare
	end
	if(button.toggle) then
		getglobal("MetaMapBWPMenu_Option"..id.."Check"):Show();
	else
		getglobal("MetaMapBWPMenu_Option"..id.."Check"):Hide();
	end
	BWP_OptionsInit()
end

function MetaMapBWPMenu_OnUpdate()
	if (MetaMapBWPMenu:IsVisible()) then
		if (not MouseIsOver(MetaMapBWPMenu) and not MouseIsOver(MetaMapBWPMenuSliderMenu)) then
			MetaMapBWPMenu:Hide();
		end
	end
end

function BWP_SetDest() --Sets the current Destination
	if(this.value.QuestGiver) then
		UIDropDownMenu_SetText(this.value.QuestGiver, BWP_MenuFrame_DropDown)
		setmininote(this.value.X,this.value.Y,this.value.QuestGiver,"7")
	elseif(this.value.title) then
		UIDropDownMenu_SetText(this.value.title, BWP_MenuFrame_DropDown)
		setmininote(this.value.xcoord, this.value.ycoord,this.value.title,"7")
	end
	BWP_OptionsInit();
end	

function BWP_GetDistText()
	local px , py = GetPlayerMapPosition("player")
	if(px == 0 and py==0) then 
		return "Dead Zone";
	end
	local dx, dy = nil,nil
	if(BWP_Destination and BWP_Destination.x and BWP_Destination.y) then
		dx, dy = BWP_Destination.x, BWP_Destination.y
	else 
		return nil 
	end
	local loc1,loc2 = {x = px , y= py},{x=dx,y=dy}
	local thisDistance, theseUnits , flag = BWP_FormatDist(loc1,loc2)
	if (flag == "A") then 
		return BWPGreenText("("..BWP_ARRIVED..")") 
	elseif flag == "Y" then 
		return "("..thisDistance..theseUnits..")"
	end
	local colortext = getglobal("BWP"..flag.."Text")
	local testtext = colortext(thisDistance..theseUnits)
	return "("..testtext..")"
end

function DeadMan()
	if(BWP_playerIsDead) then return; end
	deadx, deady = GetCorpseMapPosition();
	deadx = deadx * 100; deady = deady * 100;
	if(deadx and deady and deadx ~= 0 and deady ~= 0) then
		if(BWP_Destination) then
			BWP_OldDest = BWP_Destination;
		end
		BWP_playerIsDead = true;
		if(BWP_Options.ShowCorpse) then
			setmininote(deadx, deady, BWP_CORPSE_TEXT , "7");
		else
			BWP_DisplayFrame:Hide();
		end
	end
end

function BWP_Alive()
	if(not BWP_playerIsDead) then return; end
	if(BWP_OldDest)then
		local continent, zone = MetaMap_NameToZoneID(BWP_OldDest.zone);
		setmininote(BWP_OldDest.x, BWP_OldDest.y, BWP_OldDest.name, "7", continent, zone);
		BWP_OldDest = nil;
		BWP_playerIsDead = false;
	elseif(BWP_playerIsDead)then
		BWP_playerIsDead = false;
		BWP_ClearDest();
	end 
end

function BWP_SpecialOff()
	if(BWP_OldDest)then
		local continent, zone = MetaMap_NameToZoneID(BWP_OldDest.zone);
		setmininote(BWP_OldDest.x, BWP_OldDest.y, BWP_OldDest.name, "7", continent, zone);
		BWP_OldDest = nil;
	else
		BWP_ClearDest();
	end
	BWP_SpecialDest = 0;
end

function UnitPopup_OnClick()
	if UnitPopupMenus[this.owner][this.value]=="BWPFOLLOW" then
		BWPFOLLOW_Name = UnitName(getglobal(UIDROPDOWNMENU_INIT_MENU).unit)
		if(not BWPFOLLOWPLAYER) then
			BWP_TargetPlayer = string.lower(BWPFOLLOW_Name);
			BWP_SetSpecial = true; 
			BWP_SpecialDest = 1
			BWPFOLLOWPLAYER = 1
			DEFAULT_CHAT_FRAME:AddMessage("Now Following "..BWPFOLLOW_Name)
			UnitPopupButtons["BWPFOLLOW"] = { text = "Stop Following", dist = 0 } 
		else
			BWPFOLLOWPLAYER = nil
			BWP_SetSpecial = false; 
			BWP_SpecialDest = 0;
			BWP_ClearDest()
			DEFAULT_CHAT_FRAME:AddMessage("No Longer Following "..BWPFOLLOW_Name)
			UnitPopupButtons["BWPFOLLOW"] = { text = "Set As Waypoint", dist = 0 } 
		end	
	end
	oldBWPFOLLOW_UnitPopup_OnClick()
end 

function BWP_DropDownFrame_Initialize() --Create Dropdown
	if( UIDROPDOWNMENU_MENU_LEVEL == 1) then
		descript = {};
		descript.text = BWPGreenText("-"..BWP_NAME.." "..BWP_OPTION_TEXT.."-")
		descript.func = BWP_ShowOptions;
		UIDropDownMenu_AddButton(descript)
		
		info = {}
		info.text = BWP_SELECTMSG
		info.notClickable = 1;
		info.isTitle = 1;
		info.notCheckable = 1;
		UIDropDownMenu_AddButton(info);
		local x, y = GetPlayerMapPosition("player");
		if(x == 0 and y == 0)then 
			--Header 
			info = {
				text = BWP_NILLOCATION;
				notClickable = 1;
				isTitle = 1;
				notCheckable = 1; }
			UIDropDownMenu_AddButton(info);
			return;
		end
	end
	BWP_Generate();
	bwpx,bwpy = nil,nil
	local BWP_BREAK_IT_DOWN = nil
	if(BWP_numpoints() > 20) then BWP_BREAK_IT_DOWN = 1 end
	if(BWP_Options.ShowPoints) then
		if(not BWP_BREAK_IT_DOWN) or  ( UIDROPDOWNMENU_MENU_LEVEL == 2 ) then
			local ZonePoints = {nil}
			local isExtra = nil
			if(this.value == "BWP_CZone") then
				ZonePoints = getglobal(this.value)
			elseif(this.value) and (BWP_CZone_XTRA) and (BWP_CZone_XTRA[this.value])then
				ZonePoints = BWP_CZone_XTRA[this.value]
			elseif(not this.value) then
				ZonePoints = BWP_CZone
			end
			if(ZonePoints) then
				for val,k in ZonePoints do
					if(k) then
						title =  ZonePoints[val].title;
					end
					if (strlen(title) >= 24) then 
						title = strsub(title, 1, 21).."..."; 
					end
					if (title == "") then 
						title = SN_CZone[val]:getNote1();
					end
					descript = {}
					descript.text = val..".  "..title;
					descript.func = BWP_SetDest;
					descript.value = k;
					descript.notCheckable = 1;
					UIDropDownMenu_AddButton(descript, UIDROPDOWNMENU_MENU_LEVEL);
				end
			end
		else --Break It Down Too many Points		
			info = {};
			info.text = BWP_Get_MenuTitle(BWP_CZone);
			info.hasArrow = 1;
			info.value = "BWP_CZone";
			UIDropDownMenu_AddButton(info);
			if(BWP_CZone_XTRA) then
				for k,v in BWP_CZone_XTRA do
					if(BWP_Get_MenuTitle(v)) then
					local info = {};
					info.text = BWP_Get_MenuTitle(v);
					info.hasArrow = 1;
					info.value = k;
					UIDropDownMenu_AddButton(info);
					descript.notCheckable = 1;
					end
				end
			end
		end	
	end
	
	local LocalQList = BWP_GetQuestList()
	if(LocalQList and BWP_Options.ShowNPC) then
		if(not BWP_BREAK_IT_DOWN) or (( UIDROPDOWNMENU_MENU_LEVEL == 2 ) and (this.value == "Q")) then
			table.sort(LocalQList,BWPSortByQuestGiverName)
			local thisindex = 0
			for v, thisquest in LocalQList do
				if(thisquest) then 
					descript = {};--Make our menu Options
					descript.text = BWP_NPC_TEXT..thisquest["QuestGiver"];
					descript.func = BWP_SetDest;
					descript.value = thisquest;
					descript.notCheckable = 1;
					UIDropDownMenu_AddButton(descript,UIDROPDOWNMENU_MENU_LEVEL );
				end
			end	
		elseif(UIDROPDOWNMENU_MENU_LEVEL == 1) then
			local info = {};
				local info = {};
				info.text = BWP_QUEST_NPCSTRING	;
				info.hasArrow = 1;
				info.value = "Q";
				descript.notCheckable = 1;
				UIDropDownMenu_AddButton(info);
		end
	end
end

function BWP_Get_MenuTitle(MList)
	local tempstring = nil
	local firstword,lastword = nil, nil
	for k,v in MList do
		
		if(not tempstring) then -- if its our first word in the List
			if(v.title) then 
				tempstring = v.title 
			elseif (v.QuestGiver) then 
				tempstring = v.QuestGiver 
			end --set tempstring(so it will have a value)
			firstword = tempstring
		else
			if(v.title) then 
				tempstring = v.title 
			elseif (v.QuestGiver) then 
				tempstring = v.QuestGiver 
			end
		end
		
	end
	if(tempstring) and (firstword) then
		lastword = strsub(tempstring, 1, 5)
		firstword = strsub(firstword, 1, 5)
		return "Notes: "..firstword.." - "..lastword
	else return nil end
end

function BWP_ShowOptions()
	MetaMapBWPMenu_Init();
end

function BWP_ClearDest() --Removes current destination
	UIDropDownMenu_SetText(nil, BWP_MenuFrame_DropDown)
	if(MiniNotePOI)then
		MetaMapNotes_ClearMiniNote();
	end
	BWP_Destination = nil;
	BWP_SetSpecial = false; 
	BWP_SpecialDest = 0;
	if(BWPFOLLOWPLAYER)then	BWPFOLLOWPLAYER = nil; UnitPopupButtons["BWPFOLLOW"] = { text = "Set As Waypoint", dist = 0 }; end
	BWP_DisplayFrame:Hide();
	BWP_Arrow:SetTexture(BWP_IMAGE_PATH.."forward");
end

function BWPGreenText(inText) --TextOverride
	if (inText) then
		return BWP_Greentext..inText..FONT_COLOR_CODE_CLOSE;
	end
end
function BWPRedText(inText) --Text Override
	if (inText) then
		return BWP_Redtext..inText..FONT_COLOR_CODE_CLOSE;
	end
end
function BWPHilightText(inText)	 --Text Override
	if (inText) then
		return BWP_Highlighttext..inText..FONT_COLOR_CODE_CLOSE;
	end
end

function BWP_SpecialOn()
	local continent, zone, currentZone, mapName = MetaMap_GetCurrentMapInfo();
	local continent, zone = MetaMap_NameToZoneID(GetRealZoneText());
	local name, unknown, textureIndex, x, y;
	for landmarkIndex = 1, GetNumMapLandmarks(), 1 do
		name, unknown, textureIndex, x, y = GetMapLandmarkInfo(landmarkIndex);
		if (textureIndex == 6) then
			if(BWP_Destination) then
				BWP_OldDest = BWP_Destination;
			end
			setmininote(x, y, name, "7", continent, zone);
		end
	end
end

function clearquest(title)	--Removes a quest/questgiver
	_,_,realtitle = string.find(title,".*%[%d%]% (.*)")
	if(realtitle)then
		
		title = realtitle
	end
	if(BWP_QuestList)then
		for v, thisquest in BWP_QuestList do
			if(string.find(thisquest["QuestName"],title))then
				if(thisquest["QuestName"] == title) then
					if(BWP_Destination) and (thisquest["QuestGiver"] == BWP_Destination.name)then
						BWP_ClearDest()
					end
					
					BWP_QuestList[v]= nil
					tempQuestlist = {}
					local index = 1 
					for i,q in BWP_QuestList do
						tempQuestlist[index] = q
						index = index + 1
					end
					BWP_QuestList = tempQuestlist
				else
					BWPqnamestring=BWP_QuestList[v]["QuestName"]
					_,_,tempstring1 = string.find(BWPqnamestring,"(.*)"..title)
					_,_,tempstring2 = string.find(BWPqnamestring,".*"..title.."%,(.*)")
					if(not tempstring1)and (tempstring2)then 
						BWPqnamestring = tempstring2
					elseif(not tempstring2)and(tempstring1)then
						BWPqnamestring = tempstring1
					elseif(tempstring2) and (tempstring1) then
						BWPqnamestring = tempstring1..tempstring2
					else
						DEFAULT_CHAT_FRAME:AddMessage("ERROR ON QUEST TURN IN:BWP[Unable to perform string operation]")
					end
					BWP_QuestList[v]["QuestName"]=BWPqnamestring
				end
			end
		end
	end
end
	
function BWP_numpoints()
	if(table.getn(BWP_CZone) > 20 ) then BWP_ChecknumPOI() end
	local tempnum = 0
	if(BWP_CZone) then
			tempnum = table.getn(BWP_CZone)
	end
	if (BWP_CZone_XTRA) then 
		if(BWP_CZone_XTRA[1]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[1]) end
		if(BWP_CZone_XTRA[2]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[2]) end
		if(BWP_CZone_XTRA[3]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[3]) end
		if(BWP_CZone_XTRA[4]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[4]) end
		if(BWP_CZone_XTRA[5]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[5]) end
		if(BWP_CZone_XTRA[6]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[6]) end
		if(BWP_CZone_XTRA[7]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[7]) end
		if(BWP_CZone_XTRA[8]) then tempnum = tempnum + table.getn(BWP_CZone_XTRA[8]) end -- max number of second menus
	end
	if(BWP_QuestList) then
		for v, thisquest in BWP_QuestList do
			if(thisquest)and(thisquest.Zone == GetCurrentMapZone())then
				tempnum = tempnum + 1
			end
		end
	end
	return tempnum
end

function BWP_Special_Dest()
	if(BWPFOLLOWPLAYER)then
		if(BWP_TargetPlayer) then
			local bwpthisflag 
			local playeridindex = GetNumRaidMembers()
			if (playeridindex == 0) then playeridindex = GetNumPartyMembers();bwpthisflag = nil else  bwpthisflag = "R" end
			if (playeridindex == 0 ) then
				DEFAULT_CHAT_FRAME:AddMessage(BWPGROUPERROR)
				BWP_SpecialDest = 0;
				BWP_SetSpecial = false; 
			else
				if(bwpthisflag) then -- if its a raid group
					for x =  1, playeridindex do
					local Rname, Rrank, Rsubgroup, Rlevel, Rclass, RfileName, Rzone, Ronline = GetRaidRosterInfo(x)
						if (Rname) then
							local tempuid = "raid"..x
							if(string.lower(Rname) == BWP_TargetPlayer) then
								BWP_TargetUnitID = tempuid
								
							elseif(x == 1) then --If the player wasnt found in the current group
								DEFAULT_CHAT_FRAME:AddMessage(BWPGROUPERROR1)
								BWP_SpecialDest = 0;
								BWP_SetSpecial = false; 
								BWPFOLLOWPLAYER = nil
							end
						end
					end
				else -- its a normal PARTy
					for x = 1,playeridindex do
						if (GetPartyMember(x)) then  --Doesnt work in Raid :(
							local tempuid = "party"..x
							if(string.lower(UnitName(tempuid)) == BWP_TargetPlayer) then
								BWP_TargetUnitID = tempuid
								
							elseif(x == playeridindex) and (not BWP_TargetUnitID) then --If the player wasnt found in the current group
								DEFAULT_CHAT_FRAME:AddMessage(BWPGROUPERROR2)
								BWP_SpecialDest = 0;
								BWP_SetSpecial = flase; 
								BWPFOLLOWPLAYER = nil;
							end
						end
					end
				end
				if(BWP_TargetUnitID) then
					local posX, posY = GetPlayerMapPosition(BWP_TargetUnitID)
					BWP_TargetUnitID = nil
					BWP_Destination = {
						name = BWP_TargetPlayer,
						x = posX ,
						y = posY ,			
						zone = GetRealZoneText()}						
					BWP_SetRotation();
				end
			end
		end
	else
		if(BWP_SpecialDest == 2) then
			BWP_SetSpecial = false; 
			BWP_SpecialOn();
		end
	end
end	
			
function BWP_GetQuestList() -- Returns an Array of QuestNPC Data
	local localquestlist = {}
	if(BWP_QuestList) then
		for k,v in BWP_QuestList do
			zone = GetCurrentMapZone()
			if(v.Zone == zone) then
				table.insert(localquestlist,v)
			end
		end
	end
	return localquestlist
end

function BWP_AddQuest(questname)--Adds a quest giver to waypoint menu
	if(UnitExists("target")) and(not UnitIsPlayer("Target")) and (UnitReaction("Player", "Target")>3)and (not UnitAffectingCombat("Player"))and ((UnitName("target")~= nil)or(UnitName("target")~= "")) then
		if (not BWP_QuestList) then
	    BWP_QuestList = {}
			local Questlist ={}
			local questitem = {}
			questitem["QuestName"] = questname
			questitem["QuestGiver"] = UnitName("Target")
			questitem["X"],questitem["Y"] = GetPlayerMapPosition("Player")
			questitem["Zone"]= GetCurrentMapZone()
			Questlist[1] = questitem
			BWP_QuestList = Questlist
		else
			local Questlist = BWP_QuestList
			local questitem = {}
			local index = 0
			questitem["QuestName"] = questname
			questitem["QuestGiver"] = UnitName("Target")
			questitem["Zone"]= GetCurrentMapZone()
			questitem["X"],questitem["Y"] = GetPlayerMapPosition("Player")
			for k,v in Questlist do 
				index = index + 1
				if(UnitName("Target") == v["QuestGiver"]) then
					if(v["QuestName"])then
						questitem = nil
						questitem = v 
						if(questitem["QuestName"])then
							if(not string.find(questitem["QuestName"],questname))then
								questitem["QuestName"] = (questitem["QuestName"]..","..questname)
							end
						end
					end
					Questlist[index] = questitem
					BWP_QuestList = Questlist
					return 1
				end
			end
			Questlist[index+1] = questitem
			BWP_QuestList = Questlist
		end
	end
end

--Abandon quest to know when you drop a quest and no longer require that questgiver
function  AbandonQuest() 
	local title = GetAbandonQuestName()
	if(title)then
		DEFAULT_CHAT_FRAME:AddMessage("Abandoning:"..title)
		clearquest(title)
	end
	Old_AbandonQuest()
	return Old_AbandonQuest
end

function setmininote(x, y, name, icon, continent, zone)
	if(continent == nil or zone == nil) then
		continent, zone = MetaMap_NameToZoneID(GetRealZoneText());
	end
	if(type(continent) == "string") then return; end
	if(x >= 1) then x = x / 100; end
	if(y >= 1) then y = y / 100; end
	MetaMapNotes_AddNewNote(continent, zone, x, y, name, "", "", "MetaMapBWP", icon, 0, 0, 0, 2);
	BWP_Destination = {};
	BWP_Destination.name = name;
	BWP_Destination.x = x;
	BWP_Destination.y = y;
	BWP_Destination.zone = MetaMap_ZoneNames[continent][zone];
	BWPDestText:SetText("("..BWP_Destination.name..")");
	BWPDistanceText:SetText(BWP_GetDistText())
	BWP_DisplayFrame:Show();
end

--Set up Mini Menu
function BWP_MiniDropMenu_OnLoad()
   UIDropDownMenu_Initialize(this, BWP_MiniDropMenu_Initialize);
   UIDropDownMenu_SetWidth(80, BWP_MiniDropMenu);
end 

--Initialize minimenu with options
function BWP_MiniDropMenu_Initialize()
	local info;
	if(tempitem_XBWP) then -- Make sure you have a valid object
	   if(tempitem_XBWP.X and tempitem_XBWP.Y) then -- Make sure X and Y coords Exist(means were in same zone)
		   info = {};
		   info.text = BWP_INFO_TEXT2..tempitem_XBWP.Name..BWP_INFO_TEXT3; --Option message "Set"..$name.."as waypoint"
		   info.func = QuickSetMiniMenu; -- Function to set as destination
		   info.value = tempitem_XBWP --Pass the object value
		   tempitem_XBWP = nil
		   UIDropDownMenu_AddButton(info);
		else --X and Y dont Exist so its not in out current zone
			info = {};
			info.text = BWP_INFO_TEXT1..tempitem_XBWP.Name..BWP_INFO_TEXT3; --non click message "Must be in same zone blah blah"
			info.isTitle = 1
			tempitem_XBWP = nil
			UIDropDownMenu_AddButton(info);
		end
	end
end

--sets a mininote from the value passed by the mini menu
function  QuickSetMiniMenu()
	UIDropDownMenu_SetText(this.value.Name, BWP_MenuFrame_DropDown);
	setmininote(this.value.X,this.value.Y,this.value.Name, "7", this.value.continent, this.value.zone);
	BWP_OptionsInit();
end

function BWP_CallMenu()
	ToggleDropDownMenu(1,1,BWP_MenuFrame_DropDown, "cursor",-150,0)
end

function BWP_ShowKBMenu(id)
	local centerx, centery;
	local name = getglobal("MetaKB_ScrollFrameButton"..id.."Name"):GetText();
	local zCheck = getglobal("MetaKB_ScrollFrameButton"..id.."Coords"):GetText();
	if(string.find(zCheck, "%(%d+\.?-?%d*%)?, %(?%d+\.?-?%d*%)")) then
		local continent, zone = MetaMap_NameToZoneID(GetRealZoneText());
		local coords = MetaKB_Data[MetaKB_dbID][name][continent][zone];
		local dx = coords[2]/100 - coords[4]/100;
		local dy = coords[3]/100 - coords[1]/100;
		centerx = MetaMap_round(coords[4]/100 + dx/2, 0);
		centery = MetaMap_round(coords[1]/100 + dy/2, 0);
	end
	local cx, cy = GetCursorPosition();
	BWP_MiniDropMenu:ClearAllPoints()
	BWP_MiniDropMenu:SetPoint("BOTTOM","UIParent","BOTTOMLEFT", cx, cy)
	tempitem_XBWP ={X = centerx, Y = centery, Name = name, continent = continent, zone = zone};
	ToggleDropDownMenu(1,1,BWP_MiniDropMenu)
end

function BWP_ShowNoteMenu(id)
	local continent, zone, currentZone, mapName = MetaMap_GetCurrentMapInfo();
	if not currentZone then	return end
	tempitem_XBWP ={X = currentZone[id].xPos,Y = currentZone[id].yPos ,Name = currentZone[id].name} --call our minimenu (only option is to set waypoint)
	ToggleDropDownMenu(1,1,BWP_MiniDropMenu,"cursor",-150,0)
end


function BWP_ChecknumPOI()
	BWP_CZone_XTRA = nil
	local POIinZone = table.getn(BWP_CZone)
	if( POIinZone > 20) then
		local temp_CZone = {nil}
		BWP_CZone_XTRA = {nil}
		BWP_CZone_XTRA[1] = {nil}
		BWP_CZone_XTRA[2] = {nil}
		BWP_CZone_XTRA[3] = {nil}
		BWP_CZone_XTRA[4] = {nil}
		BWP_CZone_XTRA[5] = {nil}
		BWP_CZone_XTRA[6] = {nil}
		BWP_CZone_XTRA[7] = {nil}
		BWP_CZone_XTRA[8] = {nil}
		local BWPcount = 0
		table.sort(BWP_CZone,BWPsortbyName)
		for k,v in BWP_CZone do
			BWPcount = BWPcount + 1
			if(BWPcount < 21) then
				tinsert(temp_CZone, v)
			elseif(BWPcount < 42) then 
				tinsert(BWP_CZone_XTRA[1], v );
			elseif(BWPcount < 63) then 
				tinsert(BWP_CZone_XTRA[2], v );
			elseif(BWPcount < 84) then 
				tinsert(BWP_CZone_XTRA[3], v );
			elseif(BWPcount < 105) then 
				tinsert(BWP_CZone_XTRA[4], v );
			elseif(BWPcount < 126) then 
				tinsert(BWP_CZone_XTRA[5], v );
			elseif(BWPcount < 147) then 
				tinsert(BWP_CZone_XTRA[6], v );
			elseif(BWPcount < 168) then 
				tinsert(BWP_CZone_XTRA[7], v );
			elseif(BWPcount < 189) then 
				tinsert(BWP_CZone_XTRA[8], v );
			end
		end
		BWP_CZone = temp_CZone
	end
end


-- Constructor
function BWPnode:new(x, y, text, who) 
	return setmetatable( { xcoord = x, ycoord = y, note = text, author = who}, SNmeta);
end

-- Deconstructor
function BWPnode:delete()
	return setmetatable({}, BWPmeta);
end

--Getters
function BWPnode:getX() return self.xcoord; end
function BWPnode:getY() return self.ycoord; end
function BWPnode:getNote() return self.note; end
function BWPnode:getAuthor() return self.author; end

-- Setters
function BWPnode:setX(x) self.xcoord = x; end
function BWPnode:setY(y) self.ycoord = y; end
function BWPnode:setNote(text) self.note = text; end
function BWPnode:setAuthor(text) self.author = text; end

-- Constructor
function BWPDisp:new(x, y, who, desc, txt1, txt2, mod) 
	return setmetatable( { xcoord = x, ycoord = y, author = who, title = desc, inf1 = txt1, inf2 = txt2, type = mod }, BWPDispm);
end

-- Deconstructor
function BWPDisp:delete()
	return setmetatable({}, BWPDispm);
end

-- Getters
function BWPDisp:getX() return self.xcoord; end
function BWPDisp:getY() return self.ycoord; end
function BWPDisp:getTitle() return self.title; end
function BWPDisp:getNote1() return self.inf1; end
function BWPDisp:getNote2() return self.inf2; end
function BWPDisp:getAuthor() return self.author; end
function BWPDisp:getType() return self.type; end

function BWP_FormatCoords(x, y)
	local rx, ry, fx, fy, nx, ny;
	nx = string.format("%i", x*10000); ny = string.format("%i", y*10000);
	fx = string.format("%i", x*1000); fy = string.format("%i", y*1000);
	rx = string.format("%i", x*100); ry = string.format("%i", y*100);

	fx = tonumber(strsub(fx, strlen(fx),strlen(fx))); fy = tonumber(strsub(fy, strlen(fy), strlen(fy)));

	if (tonumber(strsub(nx, strlen(nx), strlen(nx))) >= 5) then fx = fx + 1; end
	if (tonumber(strsub(ny, strlen(ny), strlen(ny))) >= 5) then fy = fy + 1; end

	return tonumber(rx.."."..fx), tonumber(ry.."."..fy);
end

--Returns Distance(in whatever units it recieves)
function BWP_GetDist(loc1 , loc2)
	if(not loc1) or (not loc2) then return nil 
	else return math.sqrt((loc1.x - loc2.x)^2 + (loc1.y - loc2.y)^2)
	end
end

--formats to yards or meters or clicks
function BWP_FormatDist(loc1,loc2)
	local zone = GetRealZoneText();
	local thisDistance = BWP_GetDist(loc1 , loc2)
	local flag = BWP_getflag(thisDistance) -- gets the color flag based on distance in Units
	thisDistance = BWP_ConvertToYards(loc1.x, loc1.y, loc2.x, loc2.y) /10;
	if(BWP_Options.ShowYards) then
		theseUnits = " Yds"
	else
		thisDistance = thisDistance * 0.9144	
		theseUnits = " Mtrs"
	end
	thisDistance = tonumber(string.format("%.0f" , thisDistance)) -- we dont really need decimal places with this small of units
	return thisDistance, theseUnits, flag
end

function BWP_getflag(distanceinUNITS)-- Really returns a color equivilent of a distance range
	local tcd =  BWP_Options.SetDistance
	if(BWP_Options.SetDistance < 0.0040) then tcd =  0.0040 end
	if (distanceinUNITS <= (BWP_Options.SetDistance *1.215)) then 	return "A"
	elseif (distanceinUNITS < tcd * 2.452) then return "Green" --for Green Text
	elseif (distanceinUNITS < tcd * 242.5) then return "Y" --For Yellow text
	else return "Red" -- for red text
	end
end

function BWP_ConvertToYards(x1, y1, x2, y2)
	if(x1 == nil) then
		x1, y1, x2, y2 = 0, 0, 0, 0;
	end
   local dx = (x1 - x2) * 40482.686754239;
   local dy = (y1 - y2) * (40482.686754239 / 1.5);
   return math.sqrt(dx * dx + dy * dy)
end

function BWP_GetDir()
	if(not updCount)then
	 updCount = 0
	end
	updCount = updCount + 1;
	if (updCount < 2) then
		return;
	end
	updCount = 0;
	-- Find out where we are now
	local x,y = GetPlayerMapPosition("player");

	local t = GetTime();
   -- Store data if we've moved at least min sample distance
    local dx,dy = 0.00001,0.0001
	if ((x ~= 0) or (y ~= 0)) then
		dx,dy = lastX - x, lastY - y 
	end
	if ((math.abs(dx) >= MIN_SAMPLE_DISTANCE)
		or (math.abs(dy) >= MIN_SAMPLE_DISTANCE)) then
		
		lastIdx = lastIdx + 1;
		if (lastIdx > MAX_LOC_SAMPLES) then
            lastIdx = 1;
		end
		LOC_X_SAMPLES[lastIdx] = x;

        LOC_Y_SAMPLES[lastIdx] = y;

        LOC_T_SAMPLES[lastIdx] = t;

        lastX,lastY = x,y;
	end
	if (lastIdx == 0) then
      return;
   end
   
   local idx = lastIdx;
   local cx,cy,ct = LOC_X_SAMPLES[idx], LOC_Y_SAMPLES[idx];
   local ct = LOC_T_SAMPLES[idx]; 
   local cutoff = t - MAX_CUMUL_TIME;
   local tx,ty,tt;
   local found = nil;
   -- Scan back through the sample list for a long enough vector
   while (true) do
      idx = idx - 1;
      if (idx == 0) then
         idx = MAX_LOC_SAMPLES;
      end
      tx, ty, tt = LOC_X_SAMPLES[idx], LOC_Y_SAMPLES[idx], LOC_T_SAMPLES[idx];      
      -- If we ran out of samples without finding a long enough
      -- vector then stop
      if (not tt) or (tt >= ct) or (tt < cutoff)  then
		break
      end
      dx = cx - tx;
      dy = cy - ty;

      -- If this vector is finally long enough, set found flag and break
      -- dx,dy, tx,ty,tt, and idx will all be useful
		
      if ((dx*dx + dy*dy) >= MIN_CUMUL_RANGE_SQ) then
         found = true;
         break;
      end
   end
   -- Not enough data
   if (not found) then
      if (lastDeg) then
         lastDeg = nil;
      end
      return
   end
   -- If we get here we have a vector, let's convert it to degrees
	local deg = math.deg(math.atan2(dx,-dy)); 
	local loc1  , loc2 = {}, {}
	loc1.x, loc1.y = BWP_Destination.x, BWP_Destination.y
	loc2.x, loc2.y = GetPlayerMapPosition("player")
	gdclx = (loc1.x - loc2.x  );
	gdcly = (loc1.y - loc2.y );
	_,_,Arrivedyet = BWP_FormatDist(loc1,loc2)
	 if (Arrivedyet == "A")and(not BWPFOLLOWPLAYER) then
		return "Arrived!"
	end
	local goaldeg = math.deg(math.atan2(gdclx,-gdcly))
	return (goaldeg - deg)
end

function GetLocalPoints()
	local Waypoints = {} 
	local countit = 0
	local zone = GetRealZoneText();
	local cont = nil;
	local cData;

	if (BWP_Zones and BWP_Zones[zone] == 1) then cont = "Kalimdor";
	elseif (BWP_Zones and BWP_Zones[zone] == 2) then cont = "Eastern Kingdoms"; end
	if (BWP_Data[cont] and BWP_Data[cont][zone]) then	
		text = "\n"
		local temp = BWP_Data[cont][zone];
		local node = nil;
		for key in temp do
			node = setmetatable(temp[key], BWPmeta);
			cData = BWPDisp:new(node:getX(), node:getY(), node:getAuthor(), "", node:getNote(), "", "BWP");
			tinsert(Waypoints, cData);
			countit = countit + 1
		end
	end
	if (MetaMapNotes_Data) then
		local BWP_mnCont, BWP_mnZone = MetaMap_GetCurrentMapInfo();
		if (MetaMapNotes_Data[BWP_mnCont] and MetaMapNotes_Data[BWP_mnCont][BWP_mnZone]) then
			for key in MetaMapNotes_Data[BWP_mnCont][BWP_mnZone] do
				
				local adjx, adjy = MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].xPos * 100, MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].yPos* 100;
				cData = BWPDisp:new(adjx, adjy, MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].creator, MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].name, MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].inf1, MetaMapNotes_Data[BWP_mnCont][BWP_mnZone][key].inf2, "MN");
				tinsert(Waypoints, cData);
				
				countit = countit + 1
			end
		end
	end
	return Waypoints , countit
end

function BWP_Generate()
	BWP_CZone = {};
	BWP_CZone , localpoints = GetLocalPoints()
end

function BWPsortbyName(a,b) return string.lower(a.title) < string.lower(b.title) end
function BWPSortByQuestGiverName(a,b) return string.lower(a.QuestGiver) < string.lower(b.QuestGiver) end

function BWP_SetRotation(dir)
	if(dir) then
		OffSet = tonumber(dir)
		if(OffSet)then
			if(OffSet > 180 )then
				OffSet = OffSet - 360
			elseif(OffSet < -180) then
				OffSet = OffSet + 360
			end
		end
		if(dir == "Arrived!") then
			BWP_CountDown = 75
			BWP_ArrowIcon = BWP_IMAGE_PATH.."Arrived"
		elseif(OffSet)and ((OffSet >=-5) and ( OffSet <= 5))or(OffSet < -355) then 
			BWP_ArrowIcon = BWP_IMAGE_PATH.."forward"
		elseif(OffSet)and (OffSet < -5) and (OffSet >= -15) then
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FLeft+2"
		elseif(OffSet)and (OffSet < -15) and (OffSet >= -35) then
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FLeft+1"
		elseif(OffSet)and (OffSet < -35) and (OffSet >= -55) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FLeft"
		elseif(OffSet)and (OffSet < -55) and (OffSet >= -65) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FLeft-1"
		elseif(OffSet)and (OffSet < -65) and (OffSet >= -80) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FLeft-2"
		elseif(OffSet)and (OffSet < -80) and (OffSet >= -100) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."left"
		elseif(OffSet)and (OffSet < -100) and (OffSet >= -115) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BLeft-2"
		elseif(OffSet)and (OffSet < -115) and (OffSet >= -135) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BLeft-1"
		elseif(OffSet)and (OffSet < -135) and (OffSet >= -155) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BLeft"
		elseif(OffSet)and (OffSet < -155) and (OffSet >= -165) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BLeft+1"
		elseif(OffSet)and (OffSet < -165) and (OffSet >= -175) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BLeft+2"
		elseif(OffSet)and ((OffSet < -175) and (OffSet >= -190)) or((OffSet > 175) and (OffSet <= 190)) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."Backward"
		elseif(OffSet)and (OffSet > 165) and (OffSet <= 175) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BRight+2"
		elseif(OffSet)and (OffSet > 155) and (OffSet <= 165) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BRight+1"
		elseif(OffSet)and (OffSet > 135) and (OffSet <= 155) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BRight"
		elseif(OffSet)and (OffSet > 115) and (OffSet <= 135) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BRight-1"
		elseif(OffSet)and (OffSet > 100) and (OffSet <= 115) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."BRight-2"
		elseif(OffSet)and (OffSet > 80) and (OffSet <= 100) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."right"
		elseif(OffSet)and (OffSet > 65) and (OffSet <= 80) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FRight-2"
		elseif(OffSet)and (OffSet > 55) and (OffSet <= 65) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FRight-1"
		elseif(OffSet)and (OffSet > 35) and (OffSet <= 55) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FRight"
		elseif(OffSet)and (OffSet > 15) and (OffSet <= 35) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FRight+1"
		elseif(OffSet)and (OffSet > 5) and (OffSet <= 15) then	
			BWP_ArrowIcon = BWP_IMAGE_PATH.."FRight+2"
		end
	end
	if(BWP_Destination) then
		BWP_Arrow:SetTexture(BWP_ArrowIcon);
	end
end
