#!/usr/bin/env ruby -w

require 'net/http'

# WoWhead URL Format http://www.wowhead.com/?object=xxxxx
# Data is embeded as arry of arrays within a javascript call
# return mp_Embed('Searing Gorge',[[56,76.6],[64.6,49.1],[66.2,37.7],[68,75.1]],this)
module LuaRuby
  def ruby_to_lua(v)
    if v=~ /\D+/
      return "\"#{v}\""
    else
      return v
    end
  end
end
# Add to_lua method to hash and array
class Array
  include LuaRuby
  def to_lua(depth=1)
    result = "{"
    each {|v|
        if v.instance_of? Array
          result << v.to_lua(depth+1)
        elsif v.instance_of? Hash
          result << v.to_lua(depth+1)
        else
          myval = ruby_to_lua(v)
          result << "\"#{myval}\","
        end
      }
    result << "}\n"
    return result
  end
end
class Hash
  include LuaRuby
  def to_lua(depth=1)
    # code here to generate lua out
    result = ("\t" * depth) +"{\n"
    keys.each {|k|
      mykey = ruby_to_lua(k)
      myval = fetch(k)
      if myval.instance_of? Hash
        result << ("\t" * depth) + "[#{mykey}] = \n" + myval.to_lua(depth+1)
      elsif myval.instance_of? Array
        result << ("\t" * depth) + "[#{mykey}] = \n" + myval.to_lua(depth+1)
      else
        myval = ruby_to_lua(myval)
        result << ("\t" * depth)+ "[#{mykey}] = #{myval},\n"
      end
      }
    comma = ""
    if depth > 1
      comma = ","
    end
    return result << ("\t" * depth) + "}#{comma}\n"
  end
end
minerals = Hash.new
herbs = Hash.new
gases = Hash.new
#
#
zone_map = {
  "Arathi Highlands" => 1,
	"Orgrimmar" => 2,
	"Eastern Kingdoms" => 3,
	"Undercity" => 4,
	"The Barrens" => 5,
	"Darnassus" => 6,
	"Azuremyst Isle" => 7,
	"Un'Goro Crater" => 8,
	"Burning Steppes" => 9,
	"Wetlands" => 10,
	"Winterspring" => 11,
	"Dustwallow Marsh" => 12,
	"Darkshore" => 13,
	"Loch Modan" => 14,
	"Blade's Edge Mountains" => 15,
	"Durotar" => 16,
	"Silithus" => 17,
	"Shattrath City" => 18,
	"Ashenvale" => 19,
	"Azeroth" => 20,
	"Nagrand" => 21,
	"Terokkar Forest" =>22,
	"Eversong Woods" =>23,
	"Silvermoon City" => 24,
	"Tanaris" => 25,
	"Stormwind City" => 26,
	"Swamp of Sorrows" => 27,
  "Eastern Plaguelands" => 28,
	"Blasted Lands" => 29,
	"Elwynn Forest" => 30,
	"Deadwind Pass" => 31,
	"Dun Morogh" => 32,
	"The Exodar" => 33,
	"Felwood" => 34,
	"Silverpine Forest" => 35,
	"Thunder Bluff" => 36,
	"The Hinterlands" => 37,
	"Stonetalon Mountains" => 38,
	"Mulgore" => 39,
	"Hellfire Peninsula" => 40,
	"Ironforge" => 41,
	"Thousand Needles" => 42,
	"Stranglethorn Vale" => 43,
	"Badlands" => 44,
	"Teldrassil" => 45,
	"Moonglade" => 46,
	"Shadowmoon Valley" =>47,
	"Tirisfal Glades" => 48,
	"Azshara" => 49,
	"Redridge Mountains" => 50,
	"Bloodmyst Isle" => 51,
	"Western Plaguelands" => 52,
	"Alterac Mountains" => 53,
	"Westfall" => 54,
	"Duskwood" => 55,
	"Netherstorm" => 56,
	"Ghostlands" => 57,
	"Zangarmarsh" => 58,
	"Desolace" => 59,
	"Kalimdor" => 60,
	"Searing Gorge" => 61,
	"Outland" => 62,
	"Feralas" => 63,
	"Hillsbrad Foothills" => 64,
}
rare_map = {
  	204 => [202], # silver
  	205 => [203,206], # gold
  	208 => [206,214,215], # truesilver
  	209 => [212,213,207], # oozed covered silver
  	210 => [212,213,207], # ooze covered gold
  	211 => [212,213,207], # oozed covered true silver
  	217 => [206,214,215], # dark iron
  	224 => [222,223,221], # khorium
  	223 => [222],
  	441 => [440] #flame cap
}
rare_src = {
  202 => [204],
  203 => [205,206],
  206 => [208,217],
  214 => [208,217],
  215 => [208,217],
  207 => [209,210,211],
  212 => [209,210,211],
  213 => [209,210,211],
  440 => [441],
  222 => [224,223],
  223 => [224],
  221 => [224]
}
# mieral viens
mineral_map = {
  "Copper Vein"                     => [1731,201],
  "Incendicite Mineral Vein"        => [1610,219],
  "Tin Vein"                        => [1732,202],
  "Lesser Bloodstone Deposit"       => [2653,218],
  "Iron Deposit"                    => [1735,203],
  "Mithril Deposit"                 => [2040,206],
  "Ooze Covered Mithril Deposit"    => [123310,207],
  "Small Thorium Vein"              => [324,214],
  "Ooze Covered Thorium Vein"       => [123848,213],
  "Rich Thorium Vein"               => [175404,215],
  "Fel Iron Deposit"                => [181555,221],
  "Adamantite Deposit"              => [181556,222],
  "Rich Adamantite Deposit"         => [181569,223],
  "Khorium Vein"                    => [181557,224],
  "Nethercite Deposit"              => [185877,227],
  # rare nodes below
  "Silver Vein"                     => [1733,204],
  "Ooze Covered Silver Vein"        => [73940,209],
  "Ooze Covered Rich Thorium Vein"  => [177388,212],
  "Dark Iron Deposit"               => [165658,217],
  "Truesilver Deposit"              => [2047,208],
  "Ooze Covered Truesilver Deposit" => [123309,211],
  "Gold Vein"                       => [1734,205],
  "Ooze Covered Gold Vein"          => [73941,210],
  }
# Herbs
herb_map = {
  "Silverleaf" 			    => [1617,402],
  "Peacebloom" 			    => [1618,401],
  "Bloodthistle"		    => [181166,436],
  "Earthroot"			    	=> [1619,403],
  "Mageroyal" 		    	=> [1620,404],
  "Briarthorn" 		    	=> [1621,405],
  "Stranglekelp" 		  	=> [2045,407],
  "Bruiseweed" 			    => [1622,408],
  "Wild Steelbloom" 		=> [1623,409],
  "Grave Moss" 			    => [1628,410],
  "Kingsblood" 			    => [1624,411],
  "Liferoot" 				    => [2041,412],
  "Fadeleaf" 				    => [2042,413],
  "Goldthorn" 				  => [2046,414],
  "Khadgar's Whisker" 	=> [2043,415],
  "Wintersbite" 			  => [2044,416],
  "Firebloom" 				  => [2866,417],
  "Purple Lotus" 			  => [142140,418],
  "Arthas' Tears" 			=> [142141,420],
  "Sungrass" 				    => [142142,421],
  "Blindweed" 				  => [142143,422],
  "Ghost Mushroom" 		  => [142144,423],
  "Gromsblood" 			    => [142145,424],
  "Golden Sansam" 			=> [176583,425],
  "Dreamfoil" 				  => [176584,426],
  "Mountain Silversage" => [176586,427],
  "Plaguebloom" 			  => [176587,428],
  "Icecap" 				      => [176588,429],
  "Black Lotus" 			  => [176589,431],
  "Felweed" 				    => [181270,432],
  "Dreaming Glory" 		  => [181271,433],
  "Terocone" 			  	  => [181277,434],
  "Ragveil" 				    => [181275,440],
  "Flame Cap" 			  	=> [181276,441],
  "Netherbloom" 		  	=> [181279,438],
  "Nightmare Vine" 	  	=> [181280,439],
  "Mana Thistle" 		  	=> [181281,437],
  "Netherdust Bush"     => [185881,442],
}
def get_data(id)
  response = Net::HTTP.get(URI.parse("http://www.wowhead.com/?object=#{id}"))
  unless response
    raise "Data not available"
  end
  lst = response.scan(/(<a href="javascript:;" onclick="myMapper\.update\(\{zone: \d+, coords: \[(.*)\])/)[0]
  if lst.nil?
    raise "No map data for #{id}"
  end
  return lst[0].split(/<a href="javascript:;"/)
end

def get_zone_name(zone_id,zm,zone_map)
  if zm[zone_id]
    return zm[zone_id]
  else
    response = Net::HTTP.get(URI.parse("http://www.wowhead.com/?zone=#{zone_id}"))
    response =~ /\<title\>(\w.*) - (\w.*) - (\w.*)\<\/title\>/
    name = Regexp.last_match(1)
    if name
      name.rstrip!
      zm[zone_id] = name
      return name
    else
      raise "Zone #{zone_id} could not be parsed"
    end
  end
end

def process_javascript(script_line,storage,node_type,zm,zmap, rare_map, rare_src)
  zn = script_line.scan(/zone: (\d+)/)
  zone = get_zone_name(zn,zm,zmap)
  if zone != nil
    puts "Zone #{zone}"
    zone.to_s.tr!("\\","")
    if zmap[zone] != nil
    else
      puts "bad zone #{zone} as zn #{zn}"
    end
    zone = zmap[zone]
    coordinates = script_line.scan(/\[(\d+\.?\d?)\,(\d+\.?\d?)\]/)
    coordinates.each {|pair|
    id = gather_coords(pair[0].to_f,pair[1].to_f)
    unless storage[zone]
      storage[zone] = Hash.new
    end
    if storage[zone].has_key?(id) #TODO rare spawn checks here
      if rare_map.has_key?(node_type)
        if rare_map[node_type].include?(storage[zone][id]) # we didnt find the normal spawn that makes this rare
          #puts "Duplicate coords found for #{id} original type is #{storage[zone][id]} new type is #{node_type}"
        elsif rare_map.include?(storage[zone][id]) and rare_map[storage[zone][id]].include?(node_type)
          storage[zone][id] = node_type
          #puts "we had a rare already in storage, but found the normal overriding"
        end
        #puts "Duplicate coords found Orig: #{storage[zone][id]} New: #{node_type}"
      elsif rare_src.has_key?(node_type) and rare_src[node_type].include?(storage[zone][id])
        storage[zone][id] = node_type
        #puts "replacing rare spawn #{storage[zone][id]} with this normal node #{node_type}"
      else
        puts "Dup found not part of rare mappings Orig:#{storage[zone][id]} new:#{node_type}"
      end
    else
        storage[zone][id] = node_type
    end
    if block_given?
      yield
    end
  }
  else
    raise "Could find Zone #{zone}"
  end
end
def gather_coords(x,y)
  trim_terminator = 7
  if y == 100
    y = 99.9
  end
  if x == 100
    x = 99.9
  end
  id = (( (x * 1000) + 0.5).floor * 1000) + (y * 100 + 0.5).floor
  #id = ((x*100000000).round + (y*10000).round).to_s[0..trim_terminator].to_i
  #puts "input x,y = #{x},#{y} (#{id})"
  return id
end

def process_mapline(line,zoneid,node_id, map)
  offset = 0
  length = 6
  lineLength = line.length
  map[zoneid] = Hash.new
  while offset < lineLength
    x = "#{line[offset,2]}.#{line[offset+2,1]}"
    y = "#{line[offset+3,2]}.#{line[offset+5,1]}"
    offset = offset + 6
    map[zoneid][gather_coords(x.to_f,y.to_f)] = node_id
  end
end
# Main program below
# start time 78009000
start_time = Time.new

mining_sv_file = File.new("MiningData.lua", modestring="w")
herb_sv_file = File.new("HerbalismData.lua", modestring="w")
gas_sv_file = File.new("GasData.lua", modestring="w")

count1 = 0
count2 = 0
zones = {}

start_time1 = Time.new
mineral_map.keys.sort.each {|k|
    id = mineral_map[k]
    puts "Processing Mineral #{k}"
    begin
      data = get_data(id[0])
      data.each {|d|
        if d.length < 1
          next
        end
        begin
          process_javascript(d,minerals,id[1],zones,zone_map, rare_map, rare_src) {count1 += 1}
        rescue Exception => p
          puts "Processing error for #{k} == #{p}"
        end
      }
    rescue Exception => e
      puts(e)
    end
  }
mining_sv_file << "GatherMateDataMineDB = "
mining_sv_file << minerals.to_lua
mining_sv_file.close
end_time1 = Time.new
puts "Processed #{count1} minerals in #{ (end_time1.to_i-start_time1.to_i) } seconds"

start_time2 = Time.new
herb_map.keys.sort.each {|k|
    id = herb_map[k]
    puts "Processing Herb #{k}"
    begin
      data = get_data(id[0])
      data.each {|d|
        if d.length < 1
          next
        end
        begin
          process_javascript(d,herbs,id[1],zones,zone_map, rare_map, rare_src){count2 += 1}
        rescue Exception => p
          puts "Processing error for #{k} == #{p}"
        end
      }
    rescue Exception => e
      puts(e)
    end
  }
herb_sv_file << "GatherMateDataHerbDB = "
herb_sv_file << herbs.to_lua
herb_sv_file.close
end_time2 = Time.new
puts "Processed #{count2} herbs in #{ (end_time2.to_i-start_time2.to_i) } seconds"

gas_sv_file << "GatherMateDataGasDB = "
process_mapline("250430580780620760220340490660300590340270300620563436659555542225",21,301,gases)
process_mapline("568330401619430751518600531871643580699440332652",56,303,gases)
process_mapline("614587614592613583568460466470570461522210525222384419389420642466634466646471640474642470638474518208467521471535581455495330420426469537214327533341349344622631649612466378430490560540300450620374542506450380350450280360431729570190328378342412",47,304,gases)
process_mapline("580520650730590350240560160200440560460580302504607549329309090510280240300210310320320380340420381589450560630660750830780790850490",58,302,gases)
## Staticly adding gas clouds as reported on Wowhead
# http://www.wowhead.com/?maps=3518:250430580780620760220340490660300590340270300620563436659555542225 "Windy Cloud"
# http://www.wowhead.com/?maps=3523:568330401619430751518600531871643580699440332652 "Arcane Vortex"
# http://www.wowhead.com/?maps=3520:614587614592613583568460466470570461522210525222384419389420642466634466646471640474642470638474518208467521471535581455495330420426469537214327533341349344622631649612466378430490560540300450620374542506450380350450280360431729570190328378342412 "Felmist"
# http://www.wowhead.com/?maps=3521:580520650730590350240560160200440560460580302504607549329309090510280240300210310320320380340420381589450560630660750830780790850490  "Swamp Gas"
gas_sv_file << gases.to_lua
gas_sv_file.close


count = count1.to_i + count2.to_i
end_time = Time.new
puts "Processed a total of #{count} objects in #{ (end_time.to_i-start_time.to_i) } seconds"
