# CvDataStorageInterface

from CvPythonExtensions import *
import CvUtil
import _winreg
import traceback
import os
import copy
import types
import cPickle as pickle

gc = CyGlobalContext()

class dataStorage:

	def __init__(self):
		self.ffhFolderName = "Magister Modmod for FfH2"

		# data Structure : each component data must be a dict and have a key "description"
		self.data = {}

		# Trophy data structure and defaults
		defaultConfig = {
			"description" : "register current user trophy file" ,
			"user_file" : "Trophy.cfg"
			}
		defaultData = {
			"description" : "store trophies value"
			}

		dictTrophy = {
			"folder" : "Trophy" ,
			"config" : "_config.cfg" ,
			"file" : "Trophy.cfg" ,
			"default_config" : copy.deepcopy(defaultConfig) ,
			"default_data" : copy.deepcopy(defaultData)
			}
		self.data["Trophy"] = copy.deepcopy(dictTrophy)

		# init globals
		for sKey in self.data.keys() :
			self.data[sKey]["folder_path"] = ""
			self.data[sKey]["config_path"] = ""
			self.data[sKey]["file_path"] = ""
			self.data[sKey]["file_data"] = copy.deepcopy(self.data[sKey]["default_data"])

		self.folderPath = self.get_FfH_FolderPath()
		if not self.folderPath : return

		# init data folders, files and values
		for sKey in self.data.keys() :
			folder = os.path.join(self.folderPath, self.data[sKey]["folder"])
			if not self.createFolder(folder) : continue
			self.data[sKey]["folder_path"] = copy.copy(folder)

			config = os.path.join(folder, self.data[sKey]["config"])
			bValid = False
			if os.path.isfile(config) :
				dictData = self.readFile(config)
				if dictData :
					if dictData.has_key("user_file") :
						userFile = dictData["user_file"]
						filePath = os.path.join(folder, userFile)
						if os.path.isfile(filePath) :
							dictFile = self.readFile(filePath)
							if dictFile :
								self.data[sKey]["config_path"] = copy.copy(config)
								self.data[sKey]["config_data"] = copy.deepcopy(dictData)
								self.data[sKey]["file"] = copy.copy(userFile)
								self.data[sKey]["file_path"] = copy.copy(filePath)
								self.data[sKey]["file_data"] = copy.deepcopy(dictFile)
								bValid = True
			if not bValid :
				if self.writeFile(config, self.data[sKey]["default_config"]) :
					self.data[sKey]["config_path"] = copy.copy(config)
					self.data[sKey]["config_data"] = copy.deepcopy(self.data[sKey]["default_config"])

					userFile = self.data[sKey]["config_data"]["user_file"]
					filePath = os.path.join(folder, userFile)

					bDefaultFileValid = False
					if os.path.isfile(filePath) :
						dictFile = self.readFile(filePath)
						if dictFile :
							self.data[sKey]["file"] = copy.copy(userFile)
							self.data[sKey]["file_path"] = copy.copy(filePath)
							self.data[sKey]["file_data"] = copy.deepcopy(dictFile)
							bDefaultFileValid = True

					if not bDefaultFileValid :
						if self.writeFile(filePath, self.data[sKey]["default_data"]) :
							self.data[sKey]["file"] = copy.deepcopy(userFile)
							self.data[sKey]["file_path"] = copy.copy(filePath)

	# Files management
	def readFile(self, path):
		try :
			Sfile = open(path, "r")
			loadDict = pickle.load(Sfile)
			Sfile.close()

			if type(loadDict) is types.DictType :
				if loadDict.has_key("description") :
					return loadDict
		except :
			print " FfH2 -> can t read file " + repr(path)
			print traceback.format_exc()
		return {}

	def writeFile(self, path, dictData):
		try:
			Sfile = open(path, "w")
			pickle.dump(dictData, Sfile)
			Sfile.close()
			return True
		except :
			print " FfH2 -> can t write file " + repr(path)
			print traceback.format_exc()
			return False

	def get_FfH_FolderPath(self):
		folder = self.getDocFolder()
		if not folder :
			return ""
		if not os.path.isdir(folder) :
			if not self.createFolder(folder) :
				return ""
		return folder

	def createFolder(self, path):
		try :
			if os.path.isdir(path) : return True

			os.mkdir(path)
			return True
		except :
			print " FfH2 -> can t create folder " + repr(path)
			print traceback.format_exc()
			return False

	def getDocFolder(self):
		try:
			userFolder = self.regRead(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Personal")
			if not userFolder : return ""
			finalFolder =  os.path.join(userFolder, "My Games", self.ffhFolderName)
			return finalFolder
		except:
			print " FfH2 -> can t join FfH doc Folders :"
			print traceback.format_exc()
			return ""

	def regRead(self, registry, path, field):
		pathKey = _winreg.OpenKey(registry, path)
		docPath = ""
		try:
			docPath = _winreg.QueryValueEx(pathKey, field)[0]
		except:
			print " FfH2 -> can t get doc path :"
			print traceback.format_exc()
		pathKey.Close()
		return docPath

	# Data management
	def getValue(self, lTags):
		try :
			if len(lTags) <= 1 : return False, -1

			sDataType = lTags[0]
			if not self.data.has_key(sDataType) : return False, -1
			if not self.data[sDataType].has_key("file_data") : return False, -1

			d = self.data[sDataType]["file_data"]
			for sTag in lTags[1:] :
				if not d.has_key(sTag) : return False, -1
				d = d[sTag]

			return True, copy.deepcopy(d)
		except:
			print " FfH2 -> can t get value : " + repr(lTags)
			print traceback.format_exc()
			return False, -1

	def setValue(self, lTags, value):
		try :
			if len(lTags) <= 1 : return

			sDataType = lTags[0]
			if not self.data.has_key(sDataType) : return
			if not self.data[sDataType].has_key("file_data") : return

			d = self.data[sDataType]["file_data"]
			for sTag in lTags[1: -1] :
				if not d.has_key(sTag) : return
				d = d[sTag]

			d[lTags[-1]] = copy.deepcopy(value)

			if self.data[sDataType]["file_path"] :
				self.writeFile(self.data[sDataType]["file_path"], self.data[sDataType]["file_data"])
		except:
			print " FfH2 -> can t set value : " + repr(lTags)
			print traceback.format_exc()

# all use in another python module for data storage must call this variable. ie :
##import CvDataStorageInterface
##ds = CvDataStorageInterface.ds
# or create a function in this module to call.
ds = dataStorage()

# called from dll
def getTrophyValue(argsList):
	szName = argsList[0]
	bRead, val = ds.getValue(["Trophy", szName])
	if not bRead : return 0
	return val

# called from dll
def setTrophyValue(argsList):
	szName, iValue = argsList
	ds.setValue(["Trophy", szName], iValue)


