require 'pathname'
require 'stringio'
require 'sdl'
require 'msgpack'

require 'darkhall/util'

module DarkHall
	class ResourceControl
		def self.load(*args)
			self.new(*args).load
		end
	
		def initialize(dir_path)
			@dir_path = Pathname.new(dir_path)
			@table_lengths = nil
			@table = nil
		end
		
		def load
			@table_lengths = {}
			@table = {}
			
			Pathname.glob(@dir_path + '*.dat'){|path|
				LOGGER.puts "load resource package - #{path.cleanpath}"
			
				pack_name = path.basename('.dat').to_s
				path.open('rb'){|input|
					# テーブル部読み込み
					unpacker = MessagePack::Unpacker.new
					buf = ''
					table_length = 0
					
					#until unpacker.finished? do
					#	buf << input.read(1024)
					#	table_length += 1024
					#	unpacker.execute(buf, 0)
					#end
					version = input.read(1)[0]
					LOGGER.puts "  version: #{version}"
					kb_size = input.read(1)[0]
					LOGGER.puts "  file table size: #{kb_size}KB"
					kb_size.times do
						buf << input.read(1024)
						table_length += 1024
			    end
					
					unpacker.execute(buf, 0)
					@table[pack_name] = unpacker.data
					@table_lengths[pack_name] = table_length
					
					LOGGER.puts "  include #{@table[pack_name].size} entries"

					
					#@table_lengths[pack_name] = table_length
					#@table[pack_name] = unpacker.data
				}
			}
			
			return self
		end
		
		
		def load_file_body(pack_name, path)
			path = Pathname.new(path)
			pack_file_path = @dir_path + "#{pack_name}.dat"
			real_file_path = @dir_path + pack_name + path
			
			table_length = @table_lengths[pack_name]
			data = @table[pack_name][path.cleanpath.to_s.downcase] if @table and @table[pack_name]
			re = nil
			
			if table_length and data then
				Game.timelog("Load resource from pack file: #{pack_file_path} - #{path.cleanpath.to_s.downcase}"){
					open(pack_file_path, 'rb'){|f|
						f.pos = 1 + 1 + table_length + data['start']
						re = f.read(data['length'])
					}
				}
				
			else
				Game.timelog("Load resource file: #{real_file_path}"){
					open(real_file_path, 'rb'){|f|
						re = f.read
					}
				}
			end
			
			re
		end
		
		def load_enemy_surface(path)
			SDL::Surface.loadFromIO(StringIO.new(load_file_body('enemy', path)))
		end
		
		def load_picture(path)
			SDL::Surface.loadFromIO(StringIO.new(load_file_body('picture', path)))
		end
		
		def load_dungeon_texture(path)
			SDL::Surface.loadFromIO(StringIO.new(load_file_body('dungeon_texture', path)))
		end


		def load_bgm(path)
			SDL::Mixer::Music.load_from_string(load_file_body('bgm', path))
		end
		
		def load_se(path)
			SDL::Mixer::Wave.load((@dir_path + 'se' + path).to_s)
		end
	end
	
	Res = ResourceControl.load('./res')
end