#==============================================================================
=begin

Script: TMX Map Converter (RMXP)
Version: 1.0
Created By: GravitiesMind

Saves a .rxdata map file to a xml .tmx file which can be used with the program
'Tiled' - [url]http://www.mapeditor.org/[/url]

* The tile layer data is stored as Base64(uncompressed)

---How To Use---
Call Map2TMX.new in Main. After it's done it will quit.

=end
#==============================================================================
class Map2TMX
  SAVE_EVENTS = true
  SAVE_EVENT_PAGES = true
  SAVE_MAP_PROPERTIES = true
  SAVE_TILESET_PROPERTIES = true
  MAP_DIRECTORY = "Data"
  MAP_RMXP_EXT = ".rxdata"
  MAP_TMX_EXT = ".tmx"
  MAP_TMX_DATA_TILESET_NAME = "Main Tileset"
  MAP_TMX_DATA_TILESET_DIRECTORY = "../Graphics/Tilesets/"
  MAP_TMX_DATA_TILESET_IMAGE_EXT = ".png"
  MAP_TMX_DATA_OBJECT_NAME = "Events"
  MAP_TMX_DATA_OBJECT_TYPE = "event"
  MAP_TMX_DATA_LAYER_NAMES = ["Layer 1", "Layer 2", "Layer 3"]
  

#------------------------------------------------------------------------------
  def initialize
    #Get a list of map filenames from the Data directory
    mapFilenames = []
    for filename in Dir.entries(MAP_DIRECTORY)
      fullpath = MAP_DIRECTORY + "/" + filename
      if FileTest.file?(fullpath)
        isMap = !filename.scan(/Map[0-9][0-9][0-9]#{MAP_RMXP_EXT}/).empty?
        if isMap
          fileBaseName = File.basename(filename, MAP_RMXP_EXT)
          mapFilenames.push(fileBaseName)
        end
      end
    end
    #Load tileset Data
    dataTilesets = load_data("Data/Tilesets.rxdata")
    spriteProgressBar = Sprite_Map2TMXProgressBar.new
    spriteProgressBar.setMaxFilenames(mapFilenames.size)
    mapProgressGain = (100.0 / mapFilenames.size.to_f)
    #Go through each map and convert the rxdata to tmx
    for mapFilename in mapFilenames
      #Load map.rxdata
      map = load_data("#{MAP_DIRECTORY}/#{mapFilename}#{MAP_RMXP_EXT}")
      #Get Tileset Data
      tileset = dataTilesets[map.tileset_id]
      tileset_name = tileset.tileset_name
      tilesetBitmap = Bitmap.new("Graphics/Tilesets/#{tileset_name}")
      tilesetWidth = tilesetBitmap.width.to_s
      tilesetHeight = tilesetBitmap.height.to_s
      tilesetBitmap.dispose
      spriteProgressBar.setTextSrcFilename("#{mapFilename}#{MAP_RMXP_EXT}")
      spriteProgressBar.setTextDstFilename("#{mapFilename}#{MAP_TMX_EXT}")
      spriteProgressBar.setTextFileCount(mapFilenames.index(mapFilename)+1,
        mapFilenames.size)
      Graphics.update
      #Save map.rxdata to map.tmx
      file = open("#{MAP_DIRECTORY}/#{mapFilename}#{MAP_TMX_EXT}", "w")
      file.binmode
      begin
        fileWriteLine(file, '<?xml version="1.0" encoding="UTF-8"?>')
        fileWrite(file, '<map version="1.0" orientation="orthogonal" ')
        fileWrite(file, 'width="' + map.width.to_s + '" ')
        fileWrite(file, 'height="' + map.height.to_s + '" ')
        fileWriteLine(file, 'tilewidth="32" tileheight="32">')
        if SAVE_MAP_PROPERTIES
          fileWriteTab(file, 1)
          fileWriteLine(file, '<properties>')
          mapID = mapFilename[/[0-9][0-9][0-9]/].to_i
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="id" value="' +
            mapID.to_s + '"/>')
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="autoplay_bgm" value="' +
            map.autoplay_bgm.to_s + '"/>')
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="autoplay_bgs" value="' +
            map.autoplay_bgs.to_s + '"/>')
          mapBGM = getStringFromArray([map.bgm.name, map.bgm.volume,
            map.bgm.pitch])
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="bgm" value="' + mapBGM + '"/>')
          mapBGS = getStringFromArray([map.bgs.name, map.bgs.volume,
            map.bgs.pitch])
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="bgs" value="' + mapBGS + '"/>')
          fileWriteTab(file, 2)
          eList = getStringFromArray(map.encounter_list)
          fileWriteLine(file, '<property name="encounter_list" value="' +
            eList + '"/>')
          fileWriteTab(file, 2)
          fileWriteLine(file, '<property name="encounter_step" value="' +
            map.encounter_step.to_s + '"/>')
          fileWriteTab(file, 1)
          fileWriteLine(file, '</properties>')
        end
        fileWriteTab(file, 1)
        fileWriteLine(file, '<tileset firstgid="1" name="' +
          MAP_TMX_DATA_TILESET_NAME + '" tilewidth="32" tileheight="32">')
        if SAVE_TILESET_PROPERTIES
          fileWriteTab(file, 2)
          fileWriteLine(file, '<properties>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="id" value="' +
            map.tileset_id.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="name" value="' +
            tileset.name + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="tileset_name" value="' +
            tileset_name + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="panorama_name" value="' +
            tileset.panorama_name + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="panorama_hue" value="' +
            tileset.panorama_hue.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_name" value="' +
            tileset.fog_name + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_hue" value="' +
            tileset.fog_hue.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_opacity" value="' +
            tileset.fog_opacity.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_blend_type" value="' +
            tileset.fog_blend_type.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_zoom" value="' +
            tileset.fog_zoom.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_sx" value="' +
            tileset.fog_sx.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="fog_sy" value="' +
            tileset.fog_sy.to_s + '"/>')
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="battleback_name" value="' +
            tileset.battleback_name + '"/>')
          tilesetPassages = getStringFromArray(tileset.passages)
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="passages" value="' +
            tilesetPassages + '"/>')
          tilesetPriorities = getStringFromArray(tileset.priorities)
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="priorities" value="' +
            tilesetPriorities + '"/>')
          tilesetTerrainTags = getStringFromArray(tileset.terrain_tags)
          fileWriteTab(file, 3)
          fileWriteLine(file, '<property name="terrain_tags" value="' +
            tilesetTerrainTags + '"/>')
          fileWriteTab(file, 2)
          fileWriteLine(file, '</properties>')
        end
        fileWriteTab(file, 2)
        fileWrite(file, '<image source="' + MAP_TMX_DATA_TILESET_DIRECTORY +
          tileset_name + MAP_TMX_DATA_TILESET_IMAGE_EXT + '" ')
        fileWriteLine(file, 'width="' + tilesetWidth + '" height="' +
          tilesetHeight + '"/>')
        fileWriteTab(file, 1)
        fileWriteLine(file, '</tileset>')
        fileWriteTab(file, 1)
        if SAVE_EVENTS
          fileWrite(file, '<objectgroup name="' + MAP_TMX_DATA_OBJECT_NAME +
            '" width="' + map.width.to_s + '" height="' +
            map.height.to_s + '"')
          if map.events.size < 1
            fileWriteLine(file, '/>')
          else
            fileWriteLine(file, '>')
            for event in map.events.values
              fileWriteTab(file, 2)
              eventStringPosX = (event.x * 32).to_s
              eventStringPosY = (event.y * 32).to_s
              fileWriteLine(file, '<object name="' + event.name +
                '" type="' + MAP_TMX_DATA_OBJECT_TYPE + '" x="' +
                eventStringPosX + '" y="' + eventStringPosY +
                '" width="32" height="32">')
              fileWriteTab(file, 3)
              fileWriteLine(file, '<properties>')
              fileWriteTab(file, 4)
              fileWriteLine(file, '<property name="id" value="' +
                event.id.to_s + '"/>')
              if SAVE_EVENT_PAGES and !event.pages.empty?
                page = event.pages[0]
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="switch1_valid" value="' +
                  page.condition.switch1_valid.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="switch2_valid" value="' +
                  page.condition.switch2_valid.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="variable_valid" value="' +
                  page.condition.variable_valid.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="self_switch_valid" value="' +
                  page.condition.self_switch_valid.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="switch1_id" value="' +
                  page.condition.switch1_id.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="switch2_id" value="' +
                  page.condition.switch2_id.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="variable_id" value="' +
                  page.condition.variable_id.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="variable_value" value="' +
                  page.condition.variable_value.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="self_switch_ch" value="' +
                  page.condition.self_switch_ch + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="tile_id" value="' +
                  page.graphic.tile_id.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="character_name" value="' +
                  page.graphic.character_name + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="character_hue" value="' +
                  page.graphic.character_hue.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="direction" value="' +
                  page.graphic.direction.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                '<property name="pattern" value="' +
                page.graphic.pattern.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="opacity" value="' +
                  page.graphic.opacity.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="blend_type" value="' +
                  page.graphic.blend_type.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="move_type" value="' +
                  page.move_type.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="move_speed" value="' +
                  page.move_speed.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="move_frequency" value="' +
                  page.move_frequency.to_s + '"/>')
                mrList = []
                for i in 0...page.move_route.list.size
                  moveCommand = page.move_route.list[i]
                  mrList[i] = getStringFromArray([moveCommand.code,
                    getStringFromArray(moveCommand.parameters)])
                end
                mrString = getStringFromArray([page.move_route.repeat,
                  page.move_route.skippable,getStringFromArray(mrList)])
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="move_route" value="' + mrString + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="walk_anime" value="' +
                  page.walk_anime.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="step_anime" value="' +
                  page.step_anime.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="direction_fix" value="' +
                  page.direction_fix.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file, 
                  '<property name="through" value="' +
                  page.through.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file, 
                  '<property name="always_on_top" value="' +
                  page.always_on_top.to_s + '"/>')
                fileWriteTab(file, 4)
                fileWriteLine(file, 
                  '<property name="trigger" value="' +
                  page.trigger.to_s + '"/>')
                ecList = []
                for i in 0...page.list.size
                  eventCommand = page.list[i]
                  ecList[i] = getStringFromArray([eventCommand.code,
                    eventCommand.indent,
                    getStringFromArray(eventCommand.parameters)])
                end
                ecString = getStringFromArray(ecList)
                fileWriteTab(file, 4)
                fileWriteLine(file,
                  '<property name="list" value="' + ecString + '"/>')
              end
              fileWriteTab(file, 3)
              fileWriteLine(file, '</properties>')
              fileWriteTab(file, 2)
              fileWriteLine(file, '</object>')
            end
            fileWriteTab(file, 1)
            fileWriteLine(file, '</objectgroup>')
          end
        end
        for mapLayer in 0...3
          fileWriteTab(file, 1)
          fileWriteLine(file, '<layer name="' +
            MAP_TMX_DATA_LAYER_NAMES[mapLayer] + '" width="' +
            map.width.to_s + '" height="' + map.height.to_s + '">')
          fileWriteTab(file, 2)
          fileWriteLine(file, '<data encoding="base64">')
          fileWriteTab(file, 3)
          fileWriteLine(file, getMapDataString(map, mapLayer))
          fileWriteTab(file, 2)
          fileWriteLine(file, '</data>')
          fileWriteTab(file, 1)
          fileWriteLine(file, '</layer>')
        end
        fileWriteLine(file, '</map>')
      ensure
        file.close
      end
      spriteProgressBar.progress += mapProgressGain
      waitProgressBar(spriteProgressBar)
    end
    spriteProgressBar.progress = 100
    spriteProgressBar.setTextComplete
    waitProgressBar(spriteProgressBar)
    waitEnd(spriteProgressBar)
    spriteProgressBar.dispose
    exit
  end
  

#------------------------------------------------------------------------------
  def waitProgressBar(spriteProgressBar)
    loop do
      spriteProgressBar.update
      Graphics.update
      break if !spriteProgressBar.isBarMoving
    end
  end
  

#------------------------------------------------------------------------------
  def waitEnd(spriteProgressBar)
    waitTime = 100
    loop do
      Graphics.update
      Input.update
      spriteProgressBar.update
      waitTime = [waitTime-1,0].max
      break if Input.trigger?(Input::C) or waitTime == 0
    end
  end
  

#------------------------------------------------------------------------------
  def fileWrite(file, s)
    file.write(s)
  end
  

#------------------------------------------------------------------------------
  def fileWriteTab(file, amount=1)
    for i in 0...amount
      file.write(" ") #"\t"
    end
  end
  

#------------------------------------------------------------------------------
  def fileWriteLine(file, s)
    file.write("#{s}\n")
  end
  

#------------------------------------------------------------------------------
  def encode64(bin)
    s = [bin].pack('m')
    return s
  end
  

#------------------------------------------------------------------------------
  def decode64(str)
    str.unpack('m')[0]
  end
  

#------------------------------------------------------------------------------
  def getMapDataString(map, z)
    mapDataString = ""
    for y in 0...map.height
      for x in 0...map.width
        gID = map.data[x, y, z]
        #removes Autotile IDs
        if gID > 0 and gID < 384
          gID = 0
        elsif gID >= 384
          gID -= 383
        end
        mapDataString += getOctual(gID)
      end
    end
    encodedData = encode64(mapDataString)
    encodedData.gsub!(/\n/) {|s| s='' } # remove newlines
    return encodedData
  end
  

#------------------------------------------------------------------------------
  def getOctual(value)
    s = ""
    for i in 0...4
      octNum = value % 256
      s += packValueToOct(octNum)
      value = (value / 256).to_i
    end
    return s
  end
  

#------------------------------------------------------------------------------
  def packValueToOct(value)
    return [value].pack('c')
  end
  

#------------------------------------------------------------------------------
  # Accepts Table's as well
  

#------------------------------------------------------------------------------
  def getStringFromArray(array)
    s = "["
    maxsize = 0
    if array.is_a?(Table)
      maxsize = array.xsize
    else
      maxsize = array.size
    end
    for i in 0...maxsize
      obj = array[i]
      s += ',' if s.size > 1
      if obj.nil?
        s += 'nil'
      elsif obj.is_a?(Array) or obj.is_a?(Table)
        s += getStringFromArray(obj)
      else
        s += obj.to_s
      end
    end
    s += "]"
    return s
  end
  

#------------------------------------------------------------------------------
end
#==============================================================================
class Sprite_Map2TMXProgressBar
  MAX_PROGRESS = 100
  BAR_BORDER_WIDTH = 2
  BAR_WIDTH = 576
  BAR_HEIGHT = 64

  attr_accessor :posx
  attr_accessor :posy
  attr_accessor :posz
  attr_accessor :progress
  #--------------------------------------------------------------------------
  def initialize
    @viewport = nil
    setBarMoveSpeed(5)
    @progress = 0
    @posx = 320
    @posy = 416
    @posz = 0
    createSprites
    update
  end
  #--------------------------------------------------------------------------
  def dispose
    @spriteBar.bitmap.dispose
    @spriteBar.dispose
    @spriteBar = nil
    @spriteBarBG.bitmap.dispose
    @spriteBarBG.dispose
    @spriteBarBG = nil
    if @spriteTextSrcFilename.bitmap != nil
      @spriteTextSrcFilename.bitmap.dispose
    end
    @spriteTextSrcFilename.dispose
    if @spriteTextDstFilename.bitmap != nil
      @spriteTextDstFilename.bitmap.dispose
    end
    @spriteTextDstFilename.dispose
    if @spriteTextFileCount.bitmap != nil
      @spriteTextFileCount.bitmap.dispose
    end
    @spriteTextFileCount.dispose
    if @spriteTextProgress.bitmap != nil
      @spriteTextProgress.bitmap.dispose
    end
    @spriteTextProgress.dispose
  end
  #--------------------------------------------------------------------------
  def createSprites
    borderColor = Color.new(255,255,255)
    bgColor = Color.new(192,192,192)
    barColor = Color.new(0,0,255)
    @spriteBarBG = Sprite.new(@viewport)
    @spriteBarBG.bitmap = Bitmap.new(BAR_WIDTH, BAR_HEIGHT)
    @spriteBarBG.bitmap.fill_rect(0, 0, @spriteBarBG.bitmap.width,
      BAR_BORDER_WIDTH, borderColor)
    @spriteBarBG.bitmap.fill_rect(@spriteBarBG.bitmap.width-BAR_BORDER_WIDTH,
      BAR_BORDER_WIDTH, BAR_BORDER_WIDTH,
      @spriteBarBG.bitmap.height-BAR_BORDER_WIDTH, borderColor)
    @spriteBarBG.bitmap.fill_rect(0,
      @spriteBarBG.bitmap.height-BAR_BORDER_WIDTH,
      @spriteBarBG.bitmap.width-BAR_BORDER_WIDTH, BAR_BORDER_WIDTH,
      borderColor)
    @spriteBarBG.bitmap.fill_rect(0, BAR_BORDER_WIDTH, BAR_BORDER_WIDTH,
      @spriteBarBG.bitmap.height-(BAR_BORDER_WIDTH*2), borderColor)
    @spriteBarBG.bitmap.fill_rect(BAR_BORDER_WIDTH, BAR_BORDER_WIDTH,
      @spriteBarBG.bitmap.width-(BAR_BORDER_WIDTH*2),
      @spriteBarBG.bitmap.height-(BAR_BORDER_WIDTH*2), bgColor)
    @spriteBar = Sprite.new(@viewport)
    nBarWidth = @spriteBarBG.bitmap.width-(BAR_BORDER_WIDTH*2)
    nBarHeight = @spriteBarBG.bitmap.height-(BAR_BORDER_WIDTH*2)
    @spriteBar.bitmap = Bitmap.new(nBarWidth, nBarHeight)
    @spriteBar.bitmap.fill_rect(0, 0, @spriteBar.bitmap.width,
      @spriteBar.bitmap.height, barColor)
    @lastmaxprogress = MAX_PROGRESS
    @lastprogress = @progress
    @barWidth = @spriteBar.bitmap.width
    @barHeight = @spriteBar.bitmap.height
    @targetWidth = getBarTargetWidth
    setBar
    @spriteTextSrcFilename = Sprite.new(@viewport)
    @spriteTextDstFilename = Sprite.new(@viewport)
    @spriteTextFileCount = Sprite.new(@viewport)
    @spriteTextProgress = Sprite.new(@viewport)
    @spriteTextComplete = Sprite.new(@viewport)
  end
  #--------------------------------------------------------------------------
  def setMaxFilenames(max)
    speed = 20
    if max > 60
      speed = 1
    elsif max > 30
      speed = 5
    elsif max > 10
      speed = 10
    end
    setBarMoveSpeed(speed)
  end
  #--------------------------------------------------------------------------
  def setBarMoveSpeed(speed)
    @barMoveSpeed = [speed, 1].max
  end
  #--------------------------------------------------------------------------
  def setTextSrcFilename(filename)
    text = "Source Filename: #{filename}"
    dummy = Bitmap.new(32, 32)
    bSize = dummy.text_size(text)
    dummy.dispose
    if @spriteTextSrcFilename.bitmap != nil
      @spriteTextSrcFilename.bitmap.dispose
    end
    @spriteTextSrcFilename.bitmap = Bitmap.new(bSize.width, bSize.height)
    x = @posx - (BAR_WIDTH / 2)
    y = @posy - (BAR_HEIGHT / 2) - (bSize.height/2) - (32 * 4)
    @spriteTextSrcFilename.bitmap.draw_text(0, 0, bSize.width,
      bSize.height, text)
    @spriteTextSrcFilename.x = x
    @spriteTextSrcFilename.y = y
    @spriteTextSrcFilename.z = @posz
  end
  #--------------------------------------------------------------------------
  def setTextDstFilename(filename)
    text = "Destination Filename: #{filename}"
    dummy = Bitmap.new(32, 32)
    bSize = dummy.text_size(text)
    dummy.dispose
    if @spriteTextDstFilename.bitmap != nil
      @spriteTextDstFilename.bitmap.dispose
    end
    @spriteTextDstFilename.bitmap = Bitmap.new(bSize.width, bSize.height)
    x = @posx - (BAR_WIDTH / 2)
    y = @posy - (BAR_HEIGHT / 2) - (bSize.height/2) - (32 * 3)
    @spriteTextDstFilename.bitmap.draw_text(0, 0, bSize.width,
      bSize.height, text)
    @spriteTextDstFilename.x = x
    @spriteTextDstFilename.y = y
    @spriteTextDstFilename.z = @posz
  end
  #--------------------------------------------------------------------------
  def setTextFileCount(cur, max)
    text = "Converting file #{cur} of #{max}"
    dummy = Bitmap.new(32, 32)
    bSize = dummy.text_size(text)
    dummy.dispose
    if @spriteTextFileCount.bitmap != nil
      @spriteTextFileCount.bitmap.dispose
    end
    @spriteTextFileCount.bitmap = Bitmap.new(bSize.width, bSize.height)
    x = @posx - (BAR_WIDTH / 2)
    y = @posy - (BAR_HEIGHT / 2) - (bSize.height/2) - (32 * 2)
    @spriteTextFileCount.bitmap.draw_text(0, 0, bSize.width,
      bSize.height, text)
    @spriteTextFileCount.x = x
    @spriteTextFileCount.y = y
    @spriteTextFileCount.z = @posz
  end
  #--------------------------------------------------------------------------
  def setTextProgress
    text = "Total Progress: " + sprintf("%i%", @progress)
    dummy = Bitmap.new(32, 32)
    bSize = dummy.text_size(text)
    dummy.dispose
    if @spriteTextProgress.bitmap != nil
      @spriteTextProgress.bitmap.dispose
    end
    @spriteTextProgress.bitmap = Bitmap.new(bSize.width, bSize.height)
    x = @posx - (BAR_WIDTH / 2)
    y = @posy - (BAR_HEIGHT / 2) - (bSize.height/2) - (32 * 1)
    @spriteTextProgress.bitmap.draw_text(0, 0, bSize.width,
      bSize.height, text)
    @spriteTextProgress.x = x
    @spriteTextProgress.y = y
    @spriteTextProgress.z = @posz
  end
  #--------------------------------------------------------------------------
  def setTextComplete
    text = "Complete!"
    dummy = Bitmap.new(32, 32)
    dummy.font.size = 48
    bSize = dummy.text_size(text)
    dummy.dispose
    if @spriteTextComplete.bitmap != nil
      @spriteTextComplete.bitmap.dispose
    end
    @spriteTextComplete.bitmap = Bitmap.new(bSize.width, bSize.height)
    @spriteTextComplete.bitmap.font.size = 48
    x = @posx - (bSize.width / 2)
    y = @posy - (bSize.height / 2)
    @spriteTextComplete.bitmap.font.color = Color.new(0,0,0)
    @spriteTextComplete.bitmap.draw_text(-1, 0, bSize.width,
      bSize.height, text)
    @spriteTextComplete.bitmap.draw_text(1, 0, bSize.width,
      bSize.height, text)
    @spriteTextComplete.bitmap.draw_text(0, -1, bSize.width,
      bSize.height, text)
    @spriteTextComplete.bitmap.draw_text(0, 1, bSize.width,
      bSize.height, text)
    @spriteTextComplete.bitmap.font.color = Color.new(255,255,255)
    @spriteTextComplete.bitmap.draw_text(0, 0, bSize.width,
      bSize.height, text)
    @spriteTextComplete.x = x
    @spriteTextComplete.y = y
    @spriteTextComplete.z = @posz + 2
    @complete = true
    @completeCount = 0
  end
  #--------------------------------------------------------------------------
  def setBar
    @curWidth = getBarTargetWidth
    add2Bar
  end
  #--------------------------------------------------------------------------
  def getBarTargetWidth
    barPercent = @lastprogress.to_f / @lastmaxprogress.to_f
    srcWidth = (@barWidth.to_f * barPercent).round
    return srcWidth.to_f
  end
  #--------------------------------------------------------------------------
  def setBarSpeed
    widthDif = (@targetWidth - @curWidth).abs
    @barSpeed = widthDif / @barMoveSpeed
  end
  #--------------------------------------------------------------------------
  def add2Bar
    @spriteBar.src_rect.set(0, 0, @curWidth, @barHeight)
  end
  #--------------------------------------------------------------------------
  def update
    newPosx = @posx - (@spriteBarBG.bitmap.width / 2)
    newPosy = @posy - (@spriteBarBG.bitmap.height / 2)
    @spriteBarBG.x = newPosx
    @spriteBarBG.y = newPosy
    @spriteBarBG.z = @posz
    @spriteBar.x = @spriteBarBG.x + BAR_BORDER_WIDTH
    @spriteBar.y = @spriteBarBG.y + BAR_BORDER_WIDTH
    @spriteBar.z = @spriteBarBG.z + 1
    if @lastprogress != @progress or @lastmaxprogress != MAX_PROGRESS
      @lastprogress = @progress
      @lastmaxprogress = MAX_PROGRESS
      @targetWidth = getBarTargetWidth
      setTextProgress
      setBarSpeed
    end
    if @curWidth != @targetWidth
      if @targetWidth > @curWidth
        @curWidth = [@curWidth + @barSpeed, @targetWidth].min
      else
        @curWidth = [@curWidth - @barSpeed, @targetWidth].max
      end
      add2Bar
    end
    if @complete
      @spriteTextComplete.visible = (@completeCount % 40 <= 20)
      @completeCount += 1
      @completeCount = 0 if @completeCount >= 40
    end
  end
  #--------------------------------------------------------------------------
  def isBarMoving
    return (@curWidth != @targetWidth)
  end
  #--------------------------------------------------------------------------
end