=======================
= XBar Addon Creation =
=======================

By Dr. Doom

!!!!!SCRIPTERS WANTED!!!!!

If you wish to help with some custom projects that I want to put into XBar to make it more awesome than ever, please contact me.  Ideally, I need someone or someones who has the following qualities:

- Extremely well versed in Blizzard LUA and XML
- Able to analyze already written code
- Able to find solutions using wowwiki and the code derived from the Blizzard interface extraction tool
- Able to think "out of the box"
- Help find and debug errors posted by users

I have about 2 or 3 other projects that I want to incorporate into XBar that would help make it the best possible addon it can be.  If you feel you can assist with this, please contact me at drdoom5081@hotmail.com

!!!!!SCRIPTERS WANTED!!!!!

In order to create your own action bar, its best to just pick one of the other bars to copy from first.  If you want a simple, no frills cast bar, I recommend XTrapBar.  If you want to do something else with each cast (such as making the wisp Icon move with your buffs or switching action bars), I'd recommend XAspectBar or XTrackBar.  For this example, we'll use XTrapBar and create a bar for the pally blessings.

1) Copy the folder of the template mod to another folder in the addon directory (will probably be named "Copy of XTrapBar").

2) Rename the folder to what you want to name your new mod ("XBlessBar")

3) Go into the folder, and open each file individually in notepad.

4) For each file, you want to go to Edit->Replace "Trap" with "Bless".  MAKE SURE YOU SELECT MATCH CASE.  Then click Replace All.

5) Repeat for each file: "TRAP" with "BLESS", careful to MATCH CASE AGAIN.

6) Now that everything says "Bless" instead of "Trap", you need to rename the files, again where you see Trap, put in Bless.

7) Open the localization.en.lua file, and replace the list of spells with your own spells.  They must match exactly as they appear in the spell book.  Pay attention to the kind of data you have in the spell list.  Read section (b) of the Advanced Scripting Notes if you have more than just a simple spell list in your addon.  If you have additional localization files follow these steps, otherwise go to step 8:

7a) Copy one of the non-english versions from XTrackBar, and change all references of Track to Bless as described above

7b) Change the bindings to that localization.  If there are other values in the file, change them as well.

7c) Open XBlessBar.xml, you will need to add another <script file="localization.XX.lua"/> line for your localized version.

8) Open XBlessBar.lua, and change the "nbuttons" value at the top of the file to however many spells you defined in localization.en.lua

9) XTrapBar by default, only enables for a certain class.  If you don't need to test for a certain class, you would perform the following steps (Note that XBlessBar has pally spells, so you would need to skip to step 10):

9a) set the "enabled" value to true

9b) In the OnLoad procedure, remove all the lines EXCEPT the event registrations - this:RegisterEvent("...");

9c) Go to step 11

10) If you do need to test for a certain class, simply change the "HUNTER" reference in the OnLoad procedure to whatever class you need ("PALADIN" for our example)

11) Your mod is all done!  You now have a simple, no frills cast bar which you can move around and rotate, etc...  If you desire to do something more advanced with your bar, such as make it cast something other than spells, change icons dynamically (such as how TrackBar "moves" the wisp icon when you select a different form of tracking), show/hide particular icons, or add other custom options, you should read on.

*** If all you want is a simple cast bar, STOP HERE ***

============================
= Advanced Scripting Notes =
============================

This section is broken down into notes about particular files.

a) BINDINGS.XML:  Notice that the binding header listed here is the normal XBar.  All XBar bindings will be placed under one common header in the keybinding section.  If you wish to make your own, use the variable listed in localization.en.lua file instead, and change its value to whatever.

b) XBarLocalizer will automatically help you get translations for various addons.  If you have spacers, meta commands, menu headers, etc... you need to test for those and react accordingly in the Babble localization loop.  See the other various XBar addons for examples of how they test and handle their spells, it's also a good idea to look in the Babble library to see which library the localizations will be in, and call the appropriate function.

c) X....BAR.TOC:  Here is where you can list the version number and set a description for the mod.  Also, you can put your homepage in the URL section.  Notice how the mod name has the color codes after it, this marks the mod to the user as requiring XBar to work.  Where it says dependencies: XBar marks it for the WoW interface.  Also notice, that we only have one file defined, the XML file.  The LUA files (including localizations) are listed in there.

d) X....BAR.XML:  All we need to do here is define the initial Frame object, and specify which LUA files we are using.  The buttons are created dynamically.  Make sure that the frame's name matches the XBARMOD variable in the LUA file EXACTLY.

e) X....BAR.LUA:  This is where the work is done, so I'll list out important elements:

* XBARMOD = This is the internal name of the mod.  It is also the name from which we derive names of Frame objects, and save data internally, so there should be no spaces in it.

* dbver = Note that this may not match the dbver of other mods, or of XBar itself.  This is an internal database format revision number.  Your first one should be 0.  If you add custom options later in the custom checkbox or slider fields, you will need to increment this so that the users' data will reset when they download this.

* XBarModData = This is a data structure that holds internal data to the mod, and is not saved between sessions.  This is where you define aspects of the mod.  The following ones are the only ones you should need to change:

	nbuttons = the number of buttons you have on your bar
	dhorizontal = true/false - the default value of "horizontal" (is the bar horizontally oriented at first).
	dorder = "az"/"za" - this corresponds to the "reverse" option, "az" is forward, "za" is backward
	dtooltips = true/false - this is whether or not tooltips are displayed first.  If you are attempting to
	            force the XBar to do something other than cast spells (use items, macros, etc...), you might
	            want to disable this.
	booktype = BOOKTYPE_SPELL/BOOKTYPE_PET - this is the booktype all spells are referenced to.  the only
	           time you'd need to redo this is if you wanted to make a movable bar to cast pet spells.
	enabled = true/false - set this to false if the mod has special load conditions (certain classes, etc...)
	nchecks = 0 to ??? - this is where you specify how many special checkbox options you want to define.
	          If you define some, you need to add some additional values like so (N = number of the
	          box, 1,2,3...):
		checkN - the name of the variable
		dcheckN - default value for this variable

		Example:
		check1="Bless Rogues"
		dcheck1=false;
		check2="Bless Hunter Pets"
		dcheck2=true;

		To access these values later, use:
		v1=XBarData[XBarOptionSet]["mods"][XBARMOD]["Bless rogues"];
		v2=XBarData[XBarOptionSet]["mods"][XBARMOD]["Bless Hunter Pets"];
		(v1 will be false, v2 will be true, unless these values
		 are changed by the user)

		*** TO CREATE SUB MENUS ***
		If you want to make your menu options appear in sub menus, do the following:
		i)   Create values in the checkbox list to represent the menus.
		ii)  Set these values to "" (empty string)
		iii) This indicates to XBar to look for a value called mcheck# (where # corresponds)
		iv)  Set mcheck# to the name of the Menu to hold the submenu.

		Example:
		check1="Menu1"
		check2="Option1"
		check3="Option2"
		check4="Menu2"
		check5="Option3"

		The menu will have the following structure:
		|
		+-Menu1
		| |
		| +-Option1
		| |
		| +-Option2
		|
		+-Menu2
		  |
		  +-Option3

		HINT: A secret to this is that when the bar sees a spell that starts with #,
		it ignores it.  This allows you to build menus out of the spell list easily.
		See XBuffBar.lua for an example of how to implement this.

	nsliders = 0 to ??? - Same thing as checks, but using slider bars:

		sliderN	= name of the value
		dsliderN = default value
		sliderNmin = minimum value
		sliderNmax = maximum value
		sliderNstep = increment value
		sliderNformat = format string for display

		Example: if you specified a slider to go from 1 to 3 in steps of 0.5,
		         You'd get to pick values of 1,1.5,2,2.5,3.  and you should
		         format them using the string "%.1f" (will give you 1 digit
		         after the decimal point).  If you wanted integer values,
		         use the format string "%i".

		See XAspectBar for an idea of how this is implemented.

		You can create menus in the same manner as the checkbox values
	
	ftexint = Texture interrupt function.  This lets you replace the texture with your own.  Example:
		["ftexint"]=XBARMOD.."_Texture",
		-equivalent to-
		ftexint=XBlessBar_Texture,  -- Notice no quotes or ()

		function XBlessBar_Texture(texture,spellname)
		-- texture is a string value of the texture about to be used
		-- spellname is a string value of the name of the spell this is for
		-- this function returns a string value with a texture in it.
			t=texture;
			-- do some stuff
			return t;
		end function

	foptioncb = Option callback function.  Lets you know the user has changed your custom defined options.  Example:
		["foptioncb"]=XBARMOD.."_OptionCB",

		function XBlessBar_OptionCB(option,value)
		--option is a string containing the name of the option changed
		--value is the value it changed to
		----boolean for checkboxes
		----numeric for sliders
		--this function does not return any values.
		end

	fbuttoncb = Callback function to intercept the button right after it is shown.  This is where you could change
	            what the action of the button is, as you have a direct hook to the button.  Example:
		["fbuttoncb"]=XBARMOD.."_ButtonCB",

		function XBlessBar_ButtonCB(button,spellname,index)
		--button is a pointer object to the button we just made
		--spellname is the name of the spell it will cast
		--index is an integer containing the index of the button (1,2,3,etc...)
		--this function does not return any values.
		end

	fbuttonid = Callback function to intercept the spell ID about to be put into a button.  Keep in mind that
		    if a button encounters a nil ID, it will act as if the player does not know the spell, and hide
		    that button from view.  Example:
		["fbuttonid"]=XBARMOD.."_ButtonID",

		function XBlessBar_ButtonID(id,spellname)
		--id is the spell ID of spellname
		--spellname is the name of the spell it will cast
		--this function returns a new spell ID to put in place.
			newid=id;
			-- do some stuff
			return newid;
		end

		This function is the perfect place to put in custom options to hide each button by setting the
		id to nil.  Also, you could put in a slider to cast specific ranks of spells.

	forientcb = Callback function to intercept positioning data for the buttons.  Example:
		["forientcb"]=XBARMOD.."_Orient",

		function XTotemBar_Orient(index,point,anchor,anchorpoint,xdir,ydir,magnitude)
		--index is the actual button frame's index
		--point is the point on the button we are anchoring to
		--anchor is the anchor frame we are using
		--anchorpoint is the point on the anchor frame we are using
		--xdir indicates the horizontal direction (-1=left,0=no change,1=right)
		--ydir indicates the vertical direction (-1=down,0=no change,1=up)
		--magnitude indicates the amount of horizontal and vertical change
		--    (This will be equal to XBAR_SPSMALL or XBAR_SPBIG)
		--this function must return all arguments passed (except index) in order
			pt=point;
			an=anchor;
			ap=anchorpoint;
			xd=xdir;
			yd=ydir;
			mag=magnitude;
			-- do some stuff
			return pt,an,ap,xd,yd,mag;
		end

		If you change the magnitude, be sure to set it to XBAR_SPSMALL for normal button spacing, or XBAR_SPBIG for spacers

f) LOCALIZATION.xx.LUA = These files contain the various localization values, along with the spell list.  See XTrackBar or XAspectBar for examples of how to implement.  The spell list variable does not have to follow the naming convention, as you only use it in the plugin mod, but should for continuity.  This is simply a list of spells in the order you want to cast them.  If you desire to put a spacer inbetween values, make a value with a single space in it (" "), this counts as another button.  If you start the spell name with "#", it will ignore it.  This is useful for menus (See XBuffBar.lua).

OTHER NOTES:
  The plugins must handle their own events, hence the registrations in the OnLoad procedure.  If you want this mod to load on special conditions, put these registrations into an if .. then block.

Because they handle their own registrations, the mods must pass update events to the main XML file.  Note the usage of the following functions (most of which require the passage of the mod name);

XBar_Scale(XBARMOD) - Updates the scale (size) of the buttons
XBar_Update(XBARMOD) - main update function.  Note that you can make your own update function to call after this if you require additional processing.
XBar_UpdateCooldowns(XBARMOD) - updates the cooldown timers on the buttons, as well as the modulating texture if a spell cannot be cast.  If your bar has a spell that may only be cast in the presence (or absence) of another buff (such as Judgement on XSealBar), you may want to call this during PLAYER_AURAS_CHANGED.  As per XBar v1.11, this function also handles the update of the texture that shows it to be usable or not, so it should also be called from the ACTIONBAR_UPDATE_USABLE event as well
XBar_BuildPlayerName() - calling this function in the PLAYER_ENTERED_WORLD event helps ensure that the XBarPlayerName variable (which is the key to saving all data) is built so our addon registration can go through.
XBar_RegisterAddon(XBARMOD) - this function lets XBar know we're here, and XBar builds all of our buttons for us, handles the database maintenance, etc...

It is recommended you examine the data structure in the saved variables if you need to use any other data in your bar-specific functions.

If you desire to make this bar mod do anything other than cast spells, you will need advanced knowledge of scripting and how the SecureActionButtonTemplate works.  If you have such knowledge, I don't need to give you any further instructions.  :)

Meta Commands:
  These are inline commands that modify a spell in a spell list.  The command text is defined in between '&' characters at the beginning of a spell (ex. "&idhack&Alchemy").  There is only one command at this time:

  idhack - This command tells XBar to 'break' the SecureActionButtonTemplate's control of the OnClick event and intercept it with another function that will call a spell based on the ID of that spell (found by a lookup in the spellbook).  This was necessary due to Alchemy and a few other tradeskills being broken in 2.2.2  USING THIS META COMMAND MAY CAUSE TAINT (due to the fact that CastSpell is a protected function).

PATCH NOTES:
  Metadata database:  In XBar 1.15, all information that used to be stored as attributes in the buttons and frames are now in a database called XBarFrameDB.  Eg. Instead of using XAspectBarButton1:GetAttribute("XBarID"), you would use getfenv()["XBarFrameDB"]["XAspectBarButton1"]["XBarID"].  If your mod uses the attributes, you need to convert them to the current convention.

  SecureAnchorButtonTemplate: In XBar 1.17, all bars now have an accompanying StateHeader frame (ex. XAspectBarStateHeader).  To show/hide bars outside of combat, set the "state" attribute on this frame to "0" (hide) or "1" (show).  To show or hide the bars in combat, it must be linked to an accompanying SecureAnchorButtonTemplate.  The toggle button has been converted into such a frame, and as such, all visibility changes must be detected AFTER it occurs (in the XBar_Toggle() function).  Consequently as well, the XBar_UpdateToggle function no longer updates the user's preference on whether or not the bar is hidden, that must be done at the place where it happens (ie. the config window).

  Default spacing: In XBar 1.19, because cyCircled's textures may overlap, the ability to change the default spacing has been added by use of two global variables defined in XBar\XBar.lua (near the top), which may be changed by the user:

    XBAR_SPSMALL = Normal button spacing (default is 1 pixel)
    XBAR_SPBIG = "Spacer" spacing (default is 10)

    The ability to change these from the command line is not implemented or planned at this time, however if you
    want to find the right spacing, you can use a macro or simply type the commands consisting of the following:
        /script XBAR_SPSMALL = 3;
	/console reloadui

    Change the values according to what and by how much you want to change it.