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

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.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