Sol

== Intro ==
Sol is a library of useful functions and ways to get game data.
Sol Recommended usage:
* Place the latest version of Sol.lua directly in your Addons folder
* Add ../Sol.lua to your addon's TOC file
Download: 
* CurseForge.com - http://rom.curseforge.com/projects/sol/
== Currently working on ==
* Data mining - no one
* Communication - Alleris
* YOUR idea - YOU =D
== API == 
=== Packages ===
* Sol.animation
* Sol.chat
* Sol.color
* Sol.config
* Sol.hooks
* Sol.io
* Sol.math
* Sol.string
* Sol.table
* Sol.timers
* Sol.tooltips
* Sol.util
* Sol.data
** Sol.data.crafts
** Sol.data.frames
** Sol.data.items
** Sol.data.quests
** Sol.data.skills
* Sol.constants
=== Sol.animation ===
* Sol.animation.AnimateImage(addonName, frame, images, fps, onUpdateFnName)
* Sol.animation.Fade(addonName, frame, fadeToAlpha, fps, time, onUpdateFnName)
* Sol.animation.Move(addonName, frame, moveToX, moveToY, fps, time, onUpdateFnName)
* Sol.animation.Resize(addonName, frame, sizeToWidth, sizeToHeight, fps, time, sizeChildren, onUpdateFnName)
=== Sol.chat ===
* Sol.chat.FindChatTabByName(name)
=== Sol.color ===
* Sol.color.ColorText(text, hexColor)
* Sol.color.ColorTextRGB(text, r, g, b)
* Sol.color.ColorValuesToHexColor(r, g, b)
* Sol.color.DecimalToHex(decimal)
* Sol.color.PercentToHex(percent)
=== Sol.config ===
* Sol.config.ChangeTab(addonName, tab)
* Sol.config.CheckSettings(addonName, defaultSettings, settingsName, removeOld)
* Sol.config.CreateSlashCommand(command, fn, slashName, num)
* Sol.config.CreateSlashToHandleConfig(addonName, frame, command)
* Sol.config.LoadConfig(addonName, selectedTab)
* Sol.config.SaveConfig(addonName)
* Sol.config.SetupDropdown(dropdown, values, selectedIndex, width, onSelectScript)
=== Sol.hooks ===
* Sol.hooks.GetOriginalFn(addonName, fnName, frame)
* Sol.hooks.Hook(addonName, fnName, newFn, frame)
* Sol.hooks.UnHook(addonName, fnName, frame)
* Sol.hooks.UnHookAll(addonName)
=== Sol.io ===
* Sol.io.MaxRecursionLevel = 5
* Sol.io.Debug(msg, printFrame)
* Sol.io.Error(msg, printFrame)
* Sol.io.Print(msg, printFrame)
* Sol.io.Printf(msg, printFrame, ...)
* Sol.io.PrintTable(tbl, spacing, isDebug, name, visited, printFn)
* Sol.io.PrintToCombatLog(msg)
* Sol.io.PrintToDebugFrame(msg)
=== Sol.string ===
* Sol.string.EndsWith(str, ends)
* Sol.string.Split(str, delim)
* Sol.string.StartsWith(str, start)
* Sol.string.Trim(str)
=== Sol.table ===
* Sol.table.Compact(tbl)
* Sol.table.Contains(tbl, value)
* Sol.table.ContainsRegex(tbl, value)
* Sol.table.DeepCopy(tbl)
* Sol.table.GetKey(tbl, value)
* Sol.table.GetKeys(tbl)
* Sol.table.RemoveEmpty(tbl)
* Sol.table.RemoveValue(tbl, value)
=== Sol.timers ===
* Sol.timers.GetTimer(addonName, timerID)
* Sol.timers.RemoveTimer(addonName, timerID)
* Sol.timers.ScheduleTimer(addonName, delay, fn, repeatDelay, timerName, onUpdateFnName)
=== Sol.tooltip ===
* Sol.tooltip.ClearAllText (tooltip)
* Sol.tooltip.ParseItemData(tooltip)
* Sol.tooltip.ReadTooltip(tooltip)
* Sol.tooltip.SetTooltipData (tooltip, data)
=== Sol.util ===
* Sol.util.MaxSearchResults = 50
* Sol.util.Eval(str)
* Sol.util.EvalTable(str)
* Sol.util.Find(searchStr, start, ignoreCase, searchPosition)
* Sol.util.FindCombatLog()
* Sol.util.FindDebugFrame()
* Sol.util.FindInTable(tbl, searchStr, searchType, start, ignoreCase, searchPosition)
* Sol.util.FnName(fn, tbl)
* Sol.util.IsMetaKeyDown(keyName)
* Sol.util.LoadCommands()
* Sol.util.LoadFile(file)
* Sol.util.LoadFile2(file)
=== Sol.data ===
==== Sol.data.crafts ====
* Sol.data.crafts.GetCraftMaterials(itemName)
* Sol.data.crafts.GetCraftSkillIndeces(itemName)
* Sol.data.crafts.GetCraftTypeIndex(craftName)
==== Sol.data.frames ====
* Sol.data.frames.PrintChildren(printFn, frame, printFrame)
* Sol.data.frames.PrintFrameHierarchy(printFn, printFrame, printSpacing, rootFrame)
* Sol.data.frames.SetupFrameHierarchy()
* Sol.data.frames.SortFrameHierarchy(sortFn)
* Sol.data.frames.TraverseFrameHierarchy(fn, root, level)
* Sol.data.frames.WatchAllFramesForFn(fnName)
* Sol.data.frames.WatchTopLevelFrames(fnName)
==== Sol.data.items ====
* Sol.data.items.GetBagItemAttributes(bagIndex, tooltip)
* Sol.data.items.GetBagItemData(bagIndex, tooltip)
* Sol.data.items.GetBagSlots(itemName)
* Sol.data.items.GetBankSlots(itemName)
* Sol.data.items.GetTotalBagItemCount(itemName)
* Sol.data.items.GetTotalBankItemCount(itemName)
==== Sol.data.skills ====
* Sol.data.skills.GetActionBarSlot(skillName)
* Sol.data.skills.GetSkillCastTime(skillPage, skillIndex, tooltip)
* Sol.data.skills.GetSkillCost(skillPage, skillIndex, tooltip)
* Sol.data.skills.GetSkillTypes(unit)
* Sol.data.skills.GetSkillNameFromAction(actionBarSlot)
* Sol.data.skills.GetSkillNameFromIcon(iconPath)
* Sol.data.skills.GetSkillbookIndeces(skillName)
* Sol.data.skills.UnitHasBuff(unit, buffName)
* Sol.data.skills.UnitBuffIndex(unit, buffName)
* Sol.data.skills.UnitHasDeBuff(unit, debuffName)
* Sol.data.skills.UnitDeBuffIndex(unit, debuffName)
==== Sol.data.quests ====
* Sol.data.quests.FindQuests(searchStr, completionType, questType, minLevel, maxLevel)
* Sol.data.quests.GetQuestIndex(questName)
* Sol.data.quests.IsComplete(index)
=== Sol.constants ===
* Sol.constants.VERSION
* Sol.constants.SEARCH_POS_ANY = 0
* Sol.constants.SEARCH_POS_START = 1
* Sol.constants.SEARCH_POS_END = -1
* Sol.constants.SEARCH_TYPE_ANY = "any"
* Sol.constants.SEARCH_TYPE_TABLE = "table"
* Sol.constants.SEARCH_TYPE_FUNCTION = "function"
* Sol.constants.SEARCH_TYPE_STRING = "string"
* Sol.constants.SEARCH_TYPE_NUMBER = "number"
* Sol.constants.SEARCH_TYPE_BOOLEAN = "boolean"
* Sol.constants.QUEST_ALL = 0
* Sol.constants.QUEST_COMPLETE = 1
* Sol.constants.QUEST_INCOMPLETE = 2
* Sol.constants.QUEST_DAILY = 1
* Sol.constants.QUEST_NORMAL = 2
* Sol.constants.DEFAULT_ANIMATION_TIME = 1
* Sol.constants.DEFAULT_FPS = 30
* Sol.constants.FLOATING_PT_PRECISION = 0.001
== Who uses Sol ==
* AddonManager 
* ChatSettings 
* CombatLogMod 
* Keep It Simple Damage Meter 
* nkCooldown 
* nkProfBar 
* PartyHide 
* SkillQueue 
* SubSkills 
* Streamline 
* UIMeasure 
* /Who 
* Your addon! If you use Sol, add it to this list =D
== Examples ==
See the API for details on how to properly set these up. Some need to have specific elements in your XML.
=== Adding a /slash command for your addon's configuration/settings screen ===
Sol.config.CreateSlashToHandleConfig("MyAddonName", MyConfigFrame, "myslashcmd")
When the user types /myslashcmd or /myaddonname, MyConfigFrame will be shown (or hidden if it's already showing)
=== Showing options on your config screen and saving them ===
Sol.config.LoadConfig("MyAddonName", MyConfigPagesSelectedTab)
Goes through MyAddonName_Settings and looks for certain frames that could match that setting. If one is found, sets its value to the setting's value (e.g., you have a boolean setting MyAddonName_Settings.ShowOnStartup; your config screen's xml defines MyAddonNameToggleShowOnStartup; after running this function, MyAddonNameToggleShowOnStartup:IsChecked() will be set to to MyAddonName_Settings.ShowOnStartup)
If MyConfigPagesSelectedTab is provided, will ChangeTab to that one.
Sol.config.SaveConfig("MyAddonName")
Goes through MyAddonName_Settings and looks for certain frames that could match that setting. If one is found, sets the *setting*'s value to be equal to the frame item's value (e.g., you have a boolean setting MyAddonName_Settings.ShowOnStartup; your config screen's xml defines MyAddonNameToggleShowOnStartup; after running this function, MyAddonName_Settings.ShowOnStartup will be set to MyAddonNameToggleShowOnStartup:IsChecked())
=== Change tabs in a multi-tabbed frame ===
Sol.config.ChangeTab("MyAddonName", TabToChangeTo)
Disables TabToChangeTo, enables currently selectedTab, hides the currently shown page frame, and shows the page from you want to switch to. 
=== Make sure all settings for your addon exist and/or update to new version ===
Sol.config.CheckSettings("MyAddonName", MyDefaultSettings)
Checks all the variables in MyDefaultSettings against those in MyAddonName_Settings and if any don't exist, they will be loaded from MyDefaultSettings. Note that it requres your settings variable to be called MyDefault_Settings.
=== Hook and use ===
Sol.hooks.Hook("MyAddonName", "AddMessage", MyAddonAddMessage, DEFAULT_CHAT_FRAME)
function MyAFunctionName(...)
 Sol.hooks.GetOriginalFn("MyAddonName", "AddMessage", DEFAULT_CHAT_FRAME)(...)
 MyDoSomething()
end
=== Print some purple text to DEFAULT_CHAT_FRAME ===
Sol.io.Print(Sol.color.ColorText("Hello world", "FF00FF"))
=== Print global frames with a name that starts with "Player" ===
local results = Sol.util.FindInTable(_G, "Player", Sol.constants.SEARCH_TYPE_TABLE, 0, false, Sol.constants.SEARCH_POS_START)
Sol.io.PrintTable(results)
results = Sol.util.FindInTable(_G, "Player", Sol.constants.SEARCH_TYPE_TABLE, Sol.util.MaxSearchResults, false, Sol.constants.SEARCH_POS_START)
Sol.io.PrintTable(results)
The first call returns the first Sol.util.MaxSearchResults (default is 50) search results; the second returns the next batch, assuming there were enough matches.
=== Reload your addon's main file without a ReloadUI() ===
Sol.util.LoadFile2("MyAddonName")
This will attempt to load Interface/Addons/MyAddonName/MyAddonName.lua
=== Add some useful debugging slash commands ===
Sol.util.LoadCommands()
=== Go through the hierarchy of frames (aka the frame tree) and print each one's name to a debug chat frame ===
Sol.data.frames.SetupFrameHierarchy()
local callback = function(node, parentNode, nodeLevel)
 Sol.io.PrintToDebugFrame(node:GetName())
end
Sol.data.frames.TraverseFrameHierarchy(callback)
Note that this is already implemented in Sol.data.frames.PrintFrameHierarchy. It is included here for illustration purposes. Also note that calls to any function in the Sol.data.frames package require Sol.data.frames.SetupFrameHierarchy() to have been run once.
=== Make a frame slowly disappear ===
Sol.animation.Fade("MyAddon", frame) 
Sol.animation.Move("MyAddon", frame, -1*frame:GetWidth())
This will change the frame's alpha to 0 (assuming it's not already at 0) and move the frame off the left side of the screen.
Note that this requires MyAddon_OnUpdate to be defined and to be receiving OnUpdate events