Notes To Myself
---------------


------------------------------------------------------------------------------
* Git setup

    git config user.name 'Mike "Xodiv" Battersby'
    git config user.email mib@post.com
    git config tag.sort version:refname
    git config fetch.prune true
    git config --global push.default simple


------------------------------------------------------------------------------
* Branch-fu

    Make a branch locally:
        git checkout -b newfeature
    List branches:
        git branch -a
    Switch between branches:
        git checkout master
        git checkout newfeature
    Push the branch to curseforge:
        git push --set-upstream origin newfeature
    Delete the branch locally:
        git branch -d newfeature
        git branch -r -d origin/newfeature
    Delete the branch on curseforge (after deleting locally):
        git push origin :newfeature
            or
        git push origin --delete newfeature
    Delete the branch locally when it's already been deleted from curseforge:
        git branch -d newfeature
        git remote prune origin
    Merge the branch into master:
        git checkout master
        git merge --log newfeature

------------------------------------------------------------------------------
* XML syntax check

    xmllint --noout UIOptionsFrame.xml


------------------------------------------------------------------------------
* To Do List

    Try to get more translations done.

    Mount weighting system.
      - How does it work with the enable/disable all button.

    Revisit and adjust/rewrite all the documentation.

    Revisit the Unavailable macro suggestion buttons.

------------------------------------------------------------------------------
* Code to check every spell usability

    I hope that someday the ability to tell if we are on top of the water
    or under it will return. WTB IsFloating()

    MAX_SPELL_ID=197177 -- from wowhead

    if not surfaceUsable then surfaceUsable = {} end
    if not underUsable then underUsable = {} end

    local function checkUsable(t)
       local i = #t + 1
       while true do
          if i > MAX_SPELL_ID then return end
          t[i] = IsUsableSpell(i)
          if i % 1000 == 0 then
             print(i)
             coroutine.yield()
          end
          i = i + 1
       end
    end

    local function compareUsable()
       for i=1,#surfaceUsable do
          if surfaceUsable[i] ~= underUsable[i] then
             print(i .. ": " .. GetSpellInfo(i))
          end
       end
    end


    local thread

    if GetMirrorTimerInfo(2) == "BREATH" then
       wipe(underUsable)
       thread = coroutine.create(function () checkUsable(underUsable) end)
    elseif IsSwimming() then
       wipe(surfaceUsable)
       thread = coroutine.create(function () checkUsable(surfaceUsable) end)
    else
       thread = coroutine.create(compareUsable)
    end

    UsableChecker = CreateFrame("Frame")
    UsableChecker:SetScript("OnUpdate", function(self, elapsed)
          if coroutine.status(thread) == "dead" then
             self:SetScript("OnUpdate", nil)
          else
             coroutine.resume(thread)
          end
    end)

------------------------------------------------------------------------------
* Running Wild under ShapeShift

    You can't use Running Wild when you are shapeshifted (e.g., you are
    transformed into a Night Elf or Human by a dungeon buff).  Unfortunately
    IsUsableSpell() still returns true in that case.


------------------------------------------------------------------------------
* Passenger-capable mounts

    Possibility of preferring a passenger-capable mount if you are in
    a group.


------------------------------------------------------------------------------
* Better "undo".

    Conclusion: seems unncessary.

    Might be able to set up the macro better for undoing in combat what we
    last did (mount -> dismount, form -> cancelform, aura -> cancelaura, etc.)
    by passing params between the PreClick handler and the PostClick handler
    as button attributes.


------------------------------------------------------------------------------
* Suggestions

    The suggestions stuff in the "last resort" macro is a bit clunky and
    is probably going to be a pain to maintain.  Consider ripping it out
    completely.

    Also since we are now testing IsSpellKnown we don't need to separate
    out the spells by class they way they are set up now.


------------------------------------------------------------------------------
* "Dragonwrath, Tarecgosa's Rest" (71086)

    Item ID 71086.  Spell ID is 101641 (Tarecgosa's Visage)

    You can only use it by "/use slot", you can't cast the spell.


------------------------------------------------------------------------------
* Might be better to look for Sea Legs aura for Vashj'ir.

    Sea legs is present even on the surface and flying so don't do it.


------------------------------------------------------------------------------
* Does GetUnitSpeed return negative if you go backwards?

    No it doesn't.


------------------------------------------------------------------------------
* Code documentation.

    Utility stuff:
        * Print.lua
            LM_Print(msg) -- prints into current active chat frame
            LM_SetDebug(onoff) -- turn debugging on/off
            LM_Debug(msg) -- prints a debug message if debugging is on
            LM_Warning(msg) -- print a msg into the UIErrorsFrame
        * AutoEventFrame.lua
            LM_CreateAutoEventFrame(frameType, ...)
                * takes the same args as CreateFrame
                * Adds an OnEvent handler that calls a function named
                  for the event. E.g., MyFrame:PLAYER_LOGIN().

    Keybinding stuff:
        * Bindings.xml
        * KeyBindingStrings.lua
            Globals for the menu entries in the blizz key menu.

    Querying stuff:
        * Location.lua
            LM_Location:CanFly()
            LM_Location:CanSwim()
            LM_Location:IsAQ()
            LM_Location:IsVashjir()
            LM_Location:IsDraenorNagrand()

    Options stuff:
        * Options.lua
            LM_Options:Initialize()

            LM_Options:AddExcludedMount(m)
            LM_Options:RemoveExcludedMount(m)
            LM_Options:SetExcludedMounts(mountList)
            LM_Options:IsExcludedMount(m)

            LM_Options:SetMountFlagBit(m, flagbit)
            LM_Options:ClearMountFlagBit(m, flagbit)
            LM_Options:ResetMountFlags(m)
            LM_Options:ApplyMountFlags(m, default_flags)

            LM_Options:GetMacro()
            LM_Options:SetMacro(macrotext)

            LM_Options:GetCombatMacro()
            LM_Options:SetCombatMacro()
            LM_Options:UseCombatMacro()

        * UI/
            Here be dragons. UI to twiddle settings in LM_Options.

    Main stuff:
        * Core.lua
            All the core logic for initialization and creating the action
            buttons that pick a mount and summon it.

        * Mount.lua
            Base class representing one mount.  Inherited by all of the
            specific class types.

            m = LM_Mount:Get('SubclassType', ...)
            m:SetupActionButton(button)
                Sets attributes on a SecureActionButton to summon this mount.
            m:IsUsable()
            m:FlagsSet() / m:CurrentFlagsSet()
            Accessor functions:
                ItemId SpellId SpellName ModelId SelfMount Name JournalIndex
                CastTime NeedsFaction NeedsProfession Flags

        * LM_*.lua
            Individual mount type classes.

        * MountList.lua
            Class for a list of mounts, used by LM_PlayerMounts.

            LM_MountList:New()
            LM_MountList:Iterate()
            LM_MountList:Shuffle()
            LM_MountList:Random()
            LM_MountList:Sort()
            LM_MountList:Search(matchfunc)

        * PlayerMounts
            All mounts the player knows.

            LM_PlayerMounts:Initialize()
            LM_PlayerMounts:ScanMounts()

            mountlist = LM_PlayerMounts:GetAllMounts()

            m = LM_PlayerMounts:GetRandomMount(flags)
                LM_PlayerMounts:GetMountBySpell(spellId)
                LM_PlayerMounts:GetMountByName(name)
                LM_PlayerMounts:GetMountByShapeshiftForm(formIndex)
            All the above calls don't return mounts for which
            LM_Options:IsExcludedMount(m) is true.
