#!/usr/bin/ruby

require 'optparse'

require 'rubygems'
require 'bindata'

require 'xtmfile/xtmheader'


class XtmJoin
	class XtmJoinArgumentError < ArgumentError ; end

	attr_reader :opts

	BUFFER_MAX_SIZE = 4096 * 4096

	def initialize args
		@args = []
		@input_filename = nil
		parse_command_line args	
	end

	def parse_command_line args
		@args = args.clone
		@opts = OptionParser.new do |opts|
			opts.banner = "Usage: #{File.basename $0} [options]\n"

			opts.separator ""
			opts.separator "Mandatory options"

			opts.on("-i", "--input FILE", "Input XTM file") do |r|
				@input_filename = r
			end

			opts.separator ""
			opts.separator "General options:"

			opts.on("-h", "--help", "Show this help") do |h|
				@help = h
			end
			opts.on("-v", "--verbose", "Show warnings too") do |v|
				@verbose = v
			end
			opts.separator ""
		end
	end

	def validate!
		@opts.parse!

		raise XtmJoinArgumentError, "No input XTM file specified!" if @input_filename.nil?

		raise RuntimeError, "Current input XTM does not exist!" unless File.exist? @input_filename 
		raise RuntimeError, "Current input XTML is not a file!" unless File.file? @input_filename
		@input_filename = File.expand_path @input_filename
	end


	def run
		validate!

		output_file = nil
		# initial file

		in_xtm = File.open @input_filename, "rb"
		header = XtmHeader::read in_xtm

		output_file = header.filename_str
		puts "Writing data to %s" % output_file

		# FIXME: prevent overwriting
		out_xtm = File.open output_file, "wb"

		cur_xtm = @input_filename
		is_first = true
		cur_size = header.filesize
		print "\x1b[s"
		while cur_size > 0 do
			unless is_first then
				cur_xtm = _nextfile cur_xtm
				puts "Opening %s" % cur_xtm
				in_xtm = File.open cur_xtm, "rb"
			end
			while cur_size > 0 and (not in_xtm.eof?) do
				pcent = ((header.filesize - cur_size) * 100 / header.filesize)

				STDOUT.print "\x1b[uProgress : %s %" % pcent
				STDOUT.flush

				read_size = if  cur_size > BUFFER_MAX_SIZE then BUFFER_MAX_SIZE
							else cur_size
							end
				buffer = in_xtm.read read_size
				cur_size = cur_size - buffer.length
				out_xtm.write buffer.slice(0, buffer.length)
			end
			is_first = false
			in_xtm.close
		end
		out_xtm.close
		STDOUT.puts ""

		# remaining files
	end

	def _nextfile curfile
		result = nil
		cur_idx = 0
		cur_len = 0
		case curfile
		when /\.([0-9]+)\.xtm$/ then
			cur_idx = $1.to_i
			cur_len = $1.length
			next_idx = cur_idx + 1
			result = curfile.gsub(/\.([0-9]+)\.xtm$/, ".%0#{cur_len}d.xtm" % next_idx)
		when /\.xtm\.([0-9]+)$/ then
			cur_idx = $1.to_i
			cur_len = $1.length
			next_idx = cur_idx + 1
			result = curfile.gsub(/\.xtm\.([0-9]+)$/, ".xtm.%0#{cur_len}d" % next_idx)
		else
			raise "Unable to detect a naming patterng for file sequence!"
		end
		return result
	end

	def self.main args
		xj = nil
		begin
			xj = XtmJoin.new args
			xj.run
			exit 0
		rescue XtmJoinArgumentError => e
			STDERR.puts "%s" % xj.opts
			STDERR.puts "error: %s" % e.message

			exit 1
		rescue SystemExit => e
			raise e
		rescue Exception => e
			STDERR.puts "error: %s" % e.message
			exit 1
		end
	end
end

XtmJoin.main ARGV