MrPlow = {}

local LibSort = LibStub:GetLibrary("LibSort-1.0")

local watchedSlots = {[SLOT_TYPE_GUILD_BANK_ITEM] = true, [SLOT_TYPE_ITEM] = true, [SLOT_TYPE_BANK_ITEM] = true }

local IS_WEAPON = { [EQUIP_TYPE_MAIN_HAND] = true, [EQUIP_TYPE_OFF_HAND] = true, [EQUIP_TYPE_ONE_HAND] = true, [EQUIP_TYPE_TWO_HAND] = true}

local WEAPON_ORDER = {
	[WEAPONTYPE_AXE] =  1,
	[WEAPONTYPE_DAGGER] =  2,
	[WEAPONTYPE_HAMMER] = 3,
	[WEAPONTYPE_SWORD] = 4,

	[WEAPONTYPE_TWO_HANDED_AXE] = 5,
	[WEAPONTYPE_TWO_HANDED_HAMMER] = 6,
	[WEAPONTYPE_TWO_HANDED_SWORD] = 7,

	[WEAPONTYPE_BOW] = 8,

	[WEAPONTYPE_FIRE_STAFF] = 9,
	[WEAPONTYPE_FROST_STAFF] =  10,
	[WEAPONTYPE_LIGHTNING_STAFF] = 11,
	[WEAPONTYPE_HEALING_STAFF] = 12,

	[WEAPONTYPE_NONE] = 13,
	[WEAPONTYPE_RUNE] = 14,
	[WEAPONTYPE_SHIELD] = 15
}

local ARMOUR_ORDER = {
	[EQUIP_TYPE_HEAD] = 1,
	[EQUIP_TYPE_NECK] = 2,
	[EQUIP_TYPE_SHOULDERS] = 3,
	[EQUIP_TYPE_CHEST] = 4,
	[EQUIP_TYPE_HAND] = 5,
	[EQUIP_TYPE_RING] = 6,
	[EQUIP_TYPE_WAIST] = 7,
	[EQUIP_TYPE_LEGS] = 8,
	[EQUIP_TYPE_FEET] = 9,

	[EQUIP_TYPE_MAIN_HAND] = 10,
	[EQUIP_TYPE_OFF_HAND] = 11,
	[EQUIP_TYPE_ONE_HAND] = 12,
	[EQUIP_TYPE_TWO_HAND] = 13,
	[EQUIP_TYPE_COSTUME] = 14,
}
local ITEM_TYPE_ORDER = {
	[ITEMTYPE_WEAPON] = 					1,
	[ITEMTYPE_ARMOR] = 						2,
	[ITEMTYPE_FOOD] = 						3,
	[ITEMTYPE_DRINK] = 						4,
	[ITEMTYPE_RECIPE] =  					5,
	[ITEMTYPE_POTION] =  					6,
	[ITEMTYPE_POISON] =   					7,
	[ITEMTYPE_CONTAINER] = 		  			8,
	[ITEMTYPE_AVA_REPAIR] =   				9,
	[ITEMTYPE_ARMOR_BOOSTER] =				10,
	[ITEMTYPE_WEAPON_BOOSTER] = 			11,
	[ITEMTYPE_BLACKSMITHING_BOOSTER] = 		12,
	[ITEMTYPE_BLACKSMITHING_RAW_MATERIAL] = 13,
	[ITEMTYPE_BLACKSMITHING_MATERIAL] = 	14,
	[ITEMTYPE_CLOTHIER_BOOSTER] = 			15,
	[ITEMTYPE_CLOTHIER_RAW_MATERIAL] = 		16,
	[ITEMTYPE_CLOTHIER_MATERIAL] = 			17,
	[ITEMTYPE_WOODWORKING_BOOSTER] = 		18,
	[ITEMTYPE_WOODWORKING_RAW_MATERIAL] = 	19,
	[ITEMTYPE_WOODWORKING_MATERIAL] = 		20,
	[ITEMTYPE_ALCHEMY_BASE] = 				21,
	[ITEMTYPE_REAGENT] = 					22,
	[ITEMTYPE_ENCHANTMENT_BOOSTER] =		23,
	[ITEMTYPE_INGREDIENT] =   				24,
	[ITEMTYPE_FLAVORING] =					25,
	[ITEMTYPE_SPICE] =						26,
	[ITEMTYPE_ADDITIVE] =					27,
	[ITEMTYPE_RAW_MATERIAL] =				28,
	[ITEMTYPE_SPELLCRAFTING_TABLET] = 		29,
	[ITEMTYPE_STYLE_MATERIAL] =   			30,
	[ITEMTYPE_GLYPH_WEAPON] =   			31,
	[ITEMTYPE_GLYPH_ARMOR] =   				32,
	[ITEMTYPE_GLYPH_JEWELRY] =   			33,
	[ITEMTYPE_RACIAL_STYLE_MOTIF] =			34,
	[ITEMTYPE_SOUL_GEM] =   				35,
	[ITEMTYPE_SIEGE] =   					36,
	[ITEMTYPE_MOUNT] =						37,
	[ITEMTYPE_LURE] = 		  				38,
	[ITEMTYPE_TRASH] = 	  					39,
	[ITEMTYPE_COSTUME] =					40,
	[ITEMTYPE_DISGUISE] =					41,
	[ITEMTYPE_TABARD] =						42,
	[ITEMTYPE_COLLECTIBLE] = 				43,
	[ITEMTYPE_TROPHY] =   					44,
	[ITEMTYPE_LOCKPICK] =					45,
	[ITEMTYPE_TOOL] =						46,
	[ITEMTYPE_ARMOR_TRAIT] =   				47,
	[ITEMTYPE_WEAPON_TRAIT] =   			48,
	[ITEMTYPE_PLUG] =						49,
	[ITEMTYPE_NONE] =						50,
	[ITEMTYPE_DEPRECATED] =					51,
}

local ENCHANTING_RUNE_ORDER = {
	[ENCHANTING_RUNE_POTENCY]	= 1,
	[ENCHANTING_RUNE_ESSENCE]	= 2,
	[ENCHANTING_RUNE_ASPECT] 	= 3,
	[ENCHANTING_RUNE_NONE]		= 4,
}

function MrPlow:Loaded(...)
	local eventCode, addonName = ...
	if addonName ~= "MrPlow" then return end

	LibSort:Register("Item Sort", "Item Type", "The type of item", "itemType", function(...) return MrPlow:ItemType(...) end)
	LibSort:Register("Item Sort", "Weapon Type", "The type of weapon", "weaponType", function(...) return MrPlow:WeaponType(...) end)
	LibSort:Register("Item Sort", "Armour Equip Type", "The type of armour", "armorEquipType", function(...) return MrPlow:ArmourEquipType(...) end)
	LibSort:Register("Item Sort", "Armour Type", "The weight of armour", "armorType", function(...) return MrPlow:ArmorType(...) end)
	LibSort:Register("Item Sort", "Crafting Type", "The crafting type of an item", "craftingType", function(...) return MrPlow:CraftingType(...) end)

	LibSort:Register("Item Sort", "Subjective Level", "The calculated subjective level", "subjectiveLevel", function(slotType, bag, index) return GetItemLevel(bag, index) end)

	LibSort:RegisterDefaultOrder("Item Sort", {"Item Type", "Weapon Type", "Armour Equip Type", "Armour Type", "Crafting Type"}, {"Subjective Level"})
end

function MrPlow:ItemType(slotType, bag, index)
	if watchedSlots[slotType] then
		return ITEM_TYPE_ORDER[GetItemType(bag, index)] or 100
	end
end

function MrPlow:WeaponType(slotType, bag, index)
	if watchedSlots[slotType] then
		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
		if equipType > 0 then
			if IS_WEAPON[equipType] then
				return WEAPON_ORDER[GetItemWeaponType(GetItemLink(bag, index))]
			end
		end
	end
end

function MrPlow:ArmorType(slotType, bag, index)
	if watchedSlots[slotType] then
		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
		if equipType <= 9 and equipType > 0  then
			return GetItemArmorType(GetItemLink(bag, index))
		end
	end
end

function MrPlow:ArmourEquipType(slotType, bag, index)
	if watchedSlots[slotType] then
		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
		return ARMOUR_ORDER[equipType]
	end
end

function MrPlow:CraftingType(slotType, bag, index)
	if watchedSlots[slotType] then
		local _, _, extra1 = GetItemCraftingInfo(bag, index)
		return ENCHANTING_RUNE_ORDER[extra1 or 4]
	end
end

EVENT_MANAGER:RegisterForEvent("MrPlowLoaded", EVENT_ADD_ON_LOADED, function(...) MrPlow:Loaded(...) end)