# Path: extract/pak_ex.py
# def get_pak_files(data, recursive = False, file_ext = None, ext_mode = EXT_MODE.suggest, toc = None):
#   
#   # If we don't have enough to even get a file count, we're obviously no good.
#   if data.len < 32:
#     raise InvalidArchiveException
#   
#   file_starts = []
#   file_ends   = []
#   filenames   = None
#   
#   if toc == None:
#     
#     file_starts, file_ends = parse_pak_toc(data)
#     num_files = len(file_starts)
#   
#   else:
#     
#     num_files = data.read("uintle:32")
#     
#     filenames = []
#     for entry in toc:
#       file_pos = entry["file_pos"]
#       file_end = file_pos + entry["file_len"]
#       filename = entry["filename"]
#       
#       file_starts.append(file_pos)
#       file_ends.append(file_end)
#       filenames.append(filename)
#   
#   ### if toc == None ###
#   
#   for i in xrange(num_files):
#     
#     file_start  = file_starts[i]
#     file_end    = file_ends[i]
#     
#     try:
#       filename, extension = os.path.splitext(filenames[i])
#       
#     except TypeError, IndexError:
#       filename = "%04d" % i
#       extension = None
#       
#       if ext_mode == EXT_MODE.auto or ext_mode == EXT_MODE.suggest:# or file_ext == None:
#         extension = guess_ext(data, file_start, file_end)
#         
#       if ext_mode == EXT_MODE.force or (ext_mode == EXT_MODE.suggest and extension == None):
#         extension = file_ext
#     
#     # Look for a null character signifying the end of text data,
#     # so we don't end up with any left-over junk or extra nulls.
#     # Since text is UTF-16, we check two bytes at a time.
#     if extension == ".txt":
#       txt_end = file_end
#       for txt_byte in xrange(file_start * 8, file_end * 8, 16):
#         if data[txt_byte : txt_byte + 8] == NULL_BYTE and data[txt_byte + 8 : txt_byte + 16] == NULL_BYTE:
#           txt_end = (txt_byte / 8) + 2
#           break
#       file_end = txt_end
#     
#     file_data = data[file_start * 8 : file_end * 8]
#     
#     #print file_start, file_end, filename, extension
#     
#     if extension == None:
#       if recursive == True:
#         try:
#           for subfile, subdata in get_pak_files(file_data, True, None):
#             full_filename = os.path.join(filename, subfile)
#             yield full_filename, subdata
#         except InvalidArchiveException:
#           extension = DEFAULT_EXT
#       else:
#         extension = DEFAULT_EXT
#     
#     if not extension == None:
#       filename = filename + extension
#       yield filename, file_data
#   
#   ### for i in xrange(num_files) ###
# 
# def parse_pak_toc(data):
#   
#   # If we don't have enough to even get a file count, we're obviously no good.
#   if data.len < 32:
#     raise InvalidArchiveException
#     
#   data.bytepos = 0
#   
#   num_files = data.read("uintle:32")
#   # One extra for the file count.
#   toc_len = (num_files + 1) * 4
#   
#   if num_files <= 0 or toc_len >= data.len / 8:
#     raise InvalidArchiveException
#   
#   file_starts = []
#   file_ends   = []
#   
#   for i in xrange(num_files):
#     file_start = data.read("uintle:32")
#     
#     # Obviously, a file can't start after the end of the archive
#     # or inside the table of contents.
#     if file_start < toc_len or file_start >= data.len / 8:
#       raise InvalidArchiveException
#       
#     # Doesn't make much sense if they're not in order.
#     if i > 0 and file_start < file_starts[-1]:
#       raise InvalidArchiveException
#     
#     file_starts.append(file_start)
#   
#   for i in xrange(num_files):
#   
#     file_start = file_starts[i]
#     if i == num_files - 1:
#       file_end = (data.len / 8)
#     else:
#       file_end = file_starts[i + 1]
#     
#     file_ends.append(file_end)
#   
#   return file_starts, file_ends


import logging
import os
import common
  import glob
from bitstring import BitStream, ConstBitStream
from extract import get_pak_files, parse_pak_toc
from gmo_file import GmoFile, GMO_MAGIC
_START = "Start"
_SIZE  = "Size"
_DATA  = "Data"

class ModelPak():
  
  def __init__(self, filename = None):
    self.__data = None
    self.__gmo_files = []
    
    if filename:
      self.load_file(filename)
  
  def load_file(self, filename):
    data = BitStream(filename = filename)
    self.load_data(data)
  
  def load_data(self, data):
    files = [entry_data for (entry_name, entry_data) in get_pak_files(data)]
    
    # There are always at least four files in a model pak.
    # The first three I don't know a lot about, and then
    # the GMO files come after that.
    if len(files) < 4:
      _LOGGER.error("Invalid model PAK. %d files found, but at least 4 needed." % len(files))
      return
    
    # The name pak contains a list of null-terminated names for
    # each of the models, stored in our standard pak format.
    name_pak = files[0]

# Path: extract/pak_ex.py
# def get_pak_files(data, recursive = False, file_ext = None, ext_mode = EXT_MODE.suggest, toc = None):
#   
#   # If we don't have enough to even get a file count, we're obviously no good.
#   if data.len < 32:
#     raise InvalidArchiveException
#   
#   file_starts = []
#   file_ends   = []
#   filenames   = None
#   
#   if toc == None:
#     
#     file_starts, file_ends = parse_pak_toc(data)
#     num_files = len(file_starts)
#   
#   else:
#     
#     num_files = data.read("uintle:32")
#     
#     filenames = []
#     for entry in toc:
#       file_pos = entry["file_pos"]
#       file_end = file_pos + entry["file_len"]
#       filename = entry["filename"]
#       
#       file_starts.append(file_pos)
#       file_ends.append(file_end)
#       filenames.append(filename)
#   
#   ### if toc == None ###
#   
#   for i in xrange(num_files):
#     
#     file_start  = file_starts[i]
#     file_end    = file_ends[i]
#     
#     try:
#       filename, extension = os.path.splitext(filenames[i])
#       
#     except TypeError, IndexError:
#       filename = "%04d" % i
#       extension = None
#       
#       if ext_mode == EXT_MODE.auto or ext_mode == EXT_MODE.suggest:# or file_ext == None:
#         extension = guess_ext(data, file_start, file_end)
#         
#       if ext_mode == EXT_MODE.force or (ext_mode == EXT_MODE.suggest and extension == None):
#         extension = file_ext
#     
#     # Look for a null character signifying the end of text data,
#     # so we don't end up with any left-over junk or extra nulls.
#     # Since text is UTF-16, we check two bytes at a time.
#     if extension == ".txt":
#       txt_end = file_end
#       for txt_byte in xrange(file_start * 8, file_end * 8, 16):
#         if data[txt_byte : txt_byte + 8] == NULL_BYTE and data[txt_byte + 8 : txt_byte + 16] == NULL_BYTE:
#           txt_end = (txt_byte / 8) + 2
#           break
#       file_end = txt_end
#     
#     file_data = data[file_start * 8 : file_end * 8]
#     
#     #print file_start, file_end, filename, extension
#     
#     if extension == None:
#       if recursive == True:
#         try:
#           for subfile, subdata in get_pak_files(file_data, True, None):
#             full_filename = os.path.join(filename, subfile)
#             yield full_filename, subdata
#         except InvalidArchiveException:
#           extension = DEFAULT_EXT
#       else:
#         extension = DEFAULT_EXT
#     
#     if not extension == None:
#       filename = filename + extension
#       yield filename, file_data
#   
#   ### for i in xrange(num_files) ###
# 
# def parse_pak_toc(data):
#   
#   # If we don't have enough to even get a file count, we're obviously no good.
#   if data.len < 32:
#     raise InvalidArchiveException
#     
#   data.bytepos = 0
#   
#   num_files = data.read("uintle:32")
#   # One extra for the file count.
#   toc_len = (num_files + 1) * 4
#   
#   if num_files <= 0 or toc_len >= data.len / 8:
#     raise InvalidArchiveException
#   
#   file_starts = []
#   file_ends   = []
#   
#   for i in xrange(num_files):
#     file_start = data.read("uintle:32")
#     
#     # Obviously, a file can't start after the end of the archive
#     # or inside the table of contents.
#     if file_start < toc_len or file_start >= data.len / 8:
#       raise InvalidArchiveException
#       
#     # Doesn't make much sense if they're not in order.
#     if i > 0 and file_start < file_starts[-1]:
#       raise InvalidArchiveException
#     
#     file_starts.append(file_start)
#   
#   for i in xrange(num_files):
#   
#     file_start = file_starts[i]
#     if i == num_files - 1:
#       file_end = (data.len / 8)
#     else:
#       file_end = file_starts[i + 1]
#     
#     file_ends.append(file_end)
#   
#   return file_starts, file_ends


# Path: model_pak.py
import logging
import os
import common
  import glob
from bitstring import BitStream, ConstBitStream
from extract import get_pak_files, parse_pak_toc
from gmo_file import GmoFile, GMO_MAGIC

_START = "Start"
_SIZE  = "Size"
_DATA  = "Data"

class ModelPak():
  
  def __init__(self, filename = None):
    self.__data = None
    self.__gmo_files = []
    
    if filename:
      self.load_file(filename)
  
  def load_file(self, filename):
    data = BitStream(filename = filename)
    self.load_data(data)
  
  def load_data(self, data):
    files = [entry_data for (entry_name, entry_data) in get_pak_files(data)]
    
    # There are always at least four files in a model pak.
    # The first three I don't know a lot about, and then
    # the GMO files come after that.
    if len(files) < 4:
      _LOGGER.error("Invalid model PAK. %d files found, but at least 4 needed." % len(files))
      return
    
    # The name pak contains a list of null-terminated names for
    # each of the models, stored in our standard pak format.
    name_pak = files[0]

    names    = [entry_data.bytes.strip('\0') for (entry_name, entry_data) in get_pak_files(name_pak)]