
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  | RingMe [EvilMaddness - Sept 4 2015]] |
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  
  DOCUMENTATION - RingMe v.60200
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  (0) CONTENT
  =============================
  - (1) Overview/Technique
  - (2) Config-Table
  - (3) Functions
  - (4) Calls

  
  (1) OVERVIEW /TECHNIQUE
  =============================
  This is Zork's old version of rRingMods that I have running up. All credit goes to Zork for making this awsome code. Here are some links Zork gave me to check out
  Check: http://www.wowinterface.com/forums/s...ht=scrollframe
  Here's some other stuff I found on the net that explains more. 
  https://en.wikipedia.org/wiki/Circular_motion
  or
  http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/Util.lua
  
  (2) CONFIG-TABLE
  =============================
  Currently the whole mod config is handled by one single table. It can handle an undetermined number of rings.
  Each ring has its own unique-id like [1], [2] and so on...
  The config for each ring is seperated into different parts that handle global, background, foreground and segment settings.
  All the important informations about color,positions,segments can be set here. You can even set a ring to not active allowing you to gather alot of configs without having to delete them.
  
  
  (3) FUNCTIONS
  =============================
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function setup_rings(id)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  - input: unique-id of the ring table
  - return: -
  
  description:
  function is called first after the "CALL". This function calls all the other create-functions that will create the 
  ring on the given unique-id. The whole config for the given unique-id is given to the variable "ring_config".
  If the ring is set to active it will be created.

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  local function cre_ring_holder(ring_config)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  - input: ring_config
  - return: ring_object
  
  description:
  function does nothing but creating the holder frame on the given config variables. All other elements will parent this object.
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function cre_ring_background(ring_config, ring_object)  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  - input: ring_config, ring_object
  - return: ring_object.background
  
  description:
  creates the background holder frame and if set in the config sets the texture and adds a rotation
  It rotation is activated a OnUpdate frame is anchored to ring_object.background that calls do_background_rotation()
  
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    local function do_background_rotation(self, elapsed)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    - input: ring_object.background, elapsed
    - return: -
    
    description:
    changes the settexcoord of the background texture to rotate around its center on a given timer.
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function cre_ring_segments(ring_config, ring_object)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  - input: ring_config, ring_object
  - return: ring_object.segments
  
  description:
  First this function creates the object and then loops from 1 to "ring_config.global.segments_used".
  In the loop a sub-object is created: ring.segments[i] this will contain every information on that given segment
  Most important information is the segment number. It gets calculated by: "calc_segment_num()"
  The segment number is saved in ring.segments[i].field
  Check the layout graphic. field = 1 -> field in the top right corner. This is done because the ring segment texture matches that part of the ring.
  All the other ring segment textures must be rorated accordingly.
  After the field number is set the function calls: "cre_segment_textures()" to create the textures for that segment.
  
  --    ring layout
  --     ____ ____
  --    /    |    \
  --    |  4 | 1  |
  --     ----+---- 
  --    |  3 | 2  |
  --    \____|____/
  --
  
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    local function calc_segment_num(ring_config,current)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    input: ring_config, current
    return: id
    
    description:
    Input value "current" is the "i-1" value from the cre_ring_segments loop. With that number, "ring_config.global.start_segment" and 
    "ring_config.global.fill_direction" the current ring segment can be calculated. Whats best is that the segments are in order of filling from bottom to top.
    This is important for later. The calulated segment id will be returned.
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    local function cre_segment_textures(ring_config,self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    input: ring_config, ring_object.segments[i]
    return: -
    
    description:
    This function has no return value but it saves alot of additional information in "ring.segments[i]"
    After the function is finished the following values are set:
    - ring_object.segments[i].direction -> fill direction
    - ring_object.segments[i].segmentsize -> segmentsize in px
    - ring_object.segments[i].outer_radius -> outer radius in px
    - ring_object.segments[i].difference -> difference between the outer radius and the segmentsize in px
    - ring_object.segments[i].inner_radius -> inner radius in px
    - ring_object.segments[i].ring_factor -> the ring factor
    - ring_object.segments[i].ring_width -> ring with in px
    
    - ring_object.segments[i].square1 -> contains the first square texture
    - ring_object.segments[i].square2 -> contains the second square texture
    - ring_object.segments[i].slicer -> contains the slicer texture
    - ring_object.segments[i].fullsegment -> contains another segment texture (this will be used if segment is fully visible and no calculations have to be made)
    
    All textures are hidden at startup.
    
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function cre_ring_foreground(ring_config, ring_object)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  input: ring_config, ring_object
  return: ring_object.foreground
  
  description:
  The function is like the one that creates the background. It creates a holder for the forground texture and if set in the config creates a background texture.
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function calc_ring_health(self,ring_config,unit)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  input: ring_object, ring_config, ring_config.global.unit
  return: -
  
  description:
  This and the mana function are just test functions I needed those to bring the ring to life. But they can help you understand how to do it.
  Since everything from your ring is saved in ring_object you have every information needed in your funtion available.
  So what does it exactly. The function is called on the UNIT_HEALTH event. It then calculates the player health and some other stuff like
  how many percent is one segment of a ring? Example if you only use 2 segments each segment is 50%, if you use 4 segments its only 25%.
  0 and 100% are special. No special calculations are needed. Just loop through all segments and hide everything (square1, square2, sliver, fullsegement) when percent = 0
  or show the fullsegement and hide everything else when percent = 100.
  If percent is something inbetween things get more tricky. Next step is: We need to find out what segment is fully visible, what is not visible at all and what has to be looked at more closely.
  The following loop handles it:
  
    for i=1, anz_seg do
      if(perc > (i*perc_per_seg)) then
        -- make segment fully visible
      elseif ((perc >= ((i-1)*perc_per_seg)) and (perc <= (i*perc_per_seg))) then
        -- percent is in this segment, calculate it
      else
        -- hide this segment completly
      end
    end
  
  What the loop does if it finds the segment that needs to be calculated it calls "calc_ring_segment()".
  
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    local function calc_ring_segment(self, value)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    input: ring_object.segments[i], value
    return: -
    
    description:
    What this function basically does is: It calculates all the needed SetTexCoord for ring_object.segments[i].square1 and ring_object.segments[i].square2 and then
    spans the slicer between the points I and O.
    Important is the direction. Some values needs to be adjusted if the direction is inverted.
    If you want to understand what this function does you need to understand SetTexCoord, otherwise it will drive you nuts.
    
    --  corners of: 
    --  segment 1  segment 2  segment 3  segment 4
    --  +-------+  +-------+  +-------+  +-------+
    --  | 1   3 |  | 2   1 |  | 4   2 |  | 3   4 |
    --  |       |  |       |  |       |  |       |
    --  | 2   4 |  | 4   3 |  | 3   1 |  | 1   2 |
    --  +-------+  +-------+  +-------+  +-------+
    --  original   90right   180right  270right
    

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function calc_ring_mana(self,ring_config,unit)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Nearly the same as the Health function, so go check it.

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  local function am(text)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  input: text
  return: -
  
  description:
  Output stuff to the chatwindow. I use this mostly when deveolping stuff to put out some values to the screen.
  
  
  (4) CALLS
  =============================
  
  Basically there is just one big call the will loop through every unique-id on the ring table and call "setup_rings()".
  The others basically the two current test scripts that will call the health and the mana function on a given event.