; Almost anything that has to do
; with values or certain ranges
; will at one point be converted
; to something else.
;
; Take for example a progressbar
; drawn using a hollow rectangle
; and a filled rectangle.
;
; You have 100 tasks to complete
; and after each task you want to
; update the progressbar.

    Tasks = 100

; The progressbar is drawn horizontally
; and has a width of the current screen.

    Width = GraphicsWidth ()

; Here's an example program:

    SetBuffer BackBuffer ()

    For Task = 1 To Tasks

        Position = Task * Width / Tasks  ; <--

        Color 0 , 64 , 128
        Rect 0 , 0 , Position , 100 , True
        Color 255 , 255 , 255
        Rect 0 , 0 , Width , 100 , False

        Flip
        Cls

    Next
    WaitKey

; Note the arrow where the magic occurs.
; Here's basically how it works:
;
;   Input value
;
;        |
;       \|/
;
;     Formula
;
;        |
;       \|/
;
;   Output value
;
; Okay, that looks just
; like any other formula.
; But this time you actually
; take out the old range
; and insert a new one.
;
;   Input  ( Old Range )  -->  Output  ( New Range )
;
; The principle is a lot like
; converting one type of variable
; to another type of variable.
;
; Here's the basic construct:
;
;   Old Value -> Divide by Old Range -> Multiply with New Range -> New Value
;
; In a formula:
;
;   New Value = Old Value / Old Range * New Range
;
; Take a look at the formula from the progressbar program.
;
;   Position = Task * Width / Tasks
;
; Task is the old value.
; Tasks is the old range.
; Width is the new range.
; Position is the new value.
;
; The order of multiplication/division
; can be swapped to increase accuracy.
;
; For example you have an old value.

    Old_Value = 1

; And an old range.

    Old_Range = 5

; You want to convert it to a new range.

    New_Range = 100

; Let's calculate it.

    New_Value = Old_Value / Old_Range * New_Range

; What's in it?

    Print New_Value
    WaitKey

; Zero!
;
; Here's what happened:
;
;   0 = 1 / 5 * 100
;
; The division happened first.
;
;   1 / 5 = 0.2
;
; And because we were using
; straight integers,
; the value was rounded to 0.
;
; I guess you know what happens next.
;
;   0 * 100 = 0
;
; So let's use floats you say.
; Alright.

    New_Value = Float Old_Value / Old_Range * New_Range

    Print New_Value
    WaitKey

; This seems to work nicely.
;
; But what if we just swap
; the order of operations instead?

    New_Value = Old_Value * New_Range / Old_Range

    Print New_Value
    WaitKey

; That works too :)
;
; So we've now calculated
; that 1 out of 5 is actually 20%
; where our old range is 5
; and our new range is 100.
;
;   Old Value
;
;     |---|---.---.---.---|  Old Range
;     '   '                '^'--..__
;     '    '                        `^`^--..__
;     '    '                                  '^'^--..__
;     '     '                                           `^`^--.._
;     |-----|-----.-----.-----.-----.-----.-----.-----.-----.-----|  New Range
;
;   New Value
;
; When you use floats
; you can actually say that
; you normalize the old value
; to a (universal) range of 1.
;
;   Uni_Value = Old_Value / Old_Range
;
; You could also call this the factor
; and people usually refer to this as the delta.
;
; There are countless number of occasions
; where you can apply this technique.
; Both in the computerworld as well as in real life.
; And I don't mean just numbers :o)
;
; What if I said each range can have
; its own starting value as well?
; Maybe you understand this already.
;
; An old value,
; with an offset/starting value,
; could be in the range of [10..20].

    Old_Value = 15

; And you want to convert it
; to a new range, being [0..5].
;
; So, the old range offset is 10.

    Old_Offset = 10

; And the old range is 20 - 10 = 10

    Old_Range = 10

; The new offset would be..

    New_Offset = 0

; And the new range is 5 - 0 = 5

    New_Range = 5

; Before we can convert the value
; from the old range to the new range
; we'd have to normalize it to an offset of zero.
; Yes, exactly like with the factor/delta.

    Old_Value = Old_Value - Old_Offset

; Now we can convert it to the new range.

    New_Value = Old_Value * New_Range / Old_Range

; And add the new range offset,
; even though it's 0.

    New_Value = New_Value + New_Offset

    Print New_Value
    WaitKey

; Satisfied? :)
;
; You can also put the entire thing in 1 big formula.

    New_Value = ( Old_Value - Old_Offset ) * New_Range / Old_Range + New_Offset

; Voila! :)
;
; This is basically also how you can make
; a zoom-in function on a radar screen
; just to name something.