import ui
import uiScriptLocale
import app
import net
import dbg
import snd
import player
import mouseModule
import wndMgr
import skill
import playersettingmodule
import quest
import localeInfo
import uiToolTip
import constInfo
import emotion
import chr
import grp
#REDDEV_MULTI_BONUS_SHOWER
import item
import chat
#ENDOF_REDDEV_MULTI_BONUS_SHOWER

SHOW_ONLY_ACTIVE_SKILL = False
SHOW_LIMIT_SUPPORT_SKILL_LIST = []
HIDE_SUPPORT_SKILL_POINT = False

if localeInfo.IsYMIR():
	SHOW_LIMIT_SUPPORT_SKILL_LIST = [121, 122, 123, 124, 126, 127, 129, 128, 131, 137, 138, 139, 140,141,142]
	if not localeInfo.IsCHEONMA():
		HIDE_SUPPORT_SKILL_POINT = True
		SHOW_LIMIT_SUPPORT_SKILL_LIST = [121, 122, 123, 124, 126, 127, 129, 128, 131, 137, 138, 139, 140,141,142]
elif localeInfo.IsJAPAN() or   (localeInfo.IsEUROPE() and app.GetLocalePath() != "locale/ca") and (localeInfo.IsEUROPE() and app.GetLocalePath() != "locale/br"):
	HIDE_SUPPORT_SKILL_POINT = True
	SHOW_LIMIT_SUPPORT_SKILL_LIST = [121, 122, 123, 124, 126, 127, 129, 128, 131, 137, 138, 139, 140]
else:
	HIDE_SUPPORT_SKILL_POINT = True

FACE_IMAGE_DICT = {
	playersettingmodule.RACE_WARRIOR_M	: "icon/face/warrior_m.tga",
	playersettingmodule.RACE_WARRIOR_W	: "icon/face/warrior_w.tga",
	playersettingmodule.RACE_ASSASSIN_M	: "icon/face/assassin_m.tga",
	playersettingmodule.RACE_ASSASSIN_W	: "icon/face/assassin_w.tga",
	playersettingmodule.RACE_SURA_M		: "icon/face/sura_m.tga",
	playersettingmodule.RACE_SURA_W		: "icon/face/sura_w.tga",
	playersettingmodule.RACE_SHAMAN_M	: "icon/face/shaman_m.tga",
	playersettingmodule.RACE_SHAMAN_W	: "icon/face/shaman_w.tga",
}
# if app.ENABLE_WOLFMAN_CHARACTER:
	# FACE_IMAGE_DICT.update({playersettingmodule.RACE_WOLFMAN_M  : "icon/face/wolfman_m.tga",})

def unsigned32(n):
	return n & 0xFFFFFFFFL

class CharacterWindow(ui.ScriptWindow):

	ACTIVE_PAGE_SLOT_COUNT = 8
	SUPPORT_PAGE_SLOT_COUNT = 12

	PAGE_SLOT_COUNT = 12
	PAGE_HORSE = 2

	SKILL_GROUP_NAME_DICT = {
		playersettingmodule.JOB_WARRIOR	: { 1 : localeInfo.SKILL_GROUP_WARRIOR_1,	2 : localeInfo.SKILL_GROUP_WARRIOR_2, },
		playersettingmodule.JOB_ASSASSIN	: { 1 : localeInfo.SKILL_GROUP_ASSASSIN_1,	2 : localeInfo.SKILL_GROUP_ASSASSIN_2, },
		playersettingmodule.JOB_SURA		: { 1 : localeInfo.SKILL_GROUP_SURA_1,		2 : localeInfo.SKILL_GROUP_SURA_2, },
		playersettingmodule.JOB_SHAMAN		: { 1 : localeInfo.SKILL_GROUP_SHAMAN_1,	2 : localeInfo.SKILL_GROUP_SHAMAN_2, },
	}
	# if app.ENABLE_WOLFMAN_CHARACTER:
		# SKILL_GROUP_NAME_DICT.update({playersettingmodule.JOB_WOLFMAN		: { 1 : localeInfo.JOB_WOLFMAN1,	2 : localeInfo.JOB_WOLFMAN2, },})

	STAT_DESCRIPTION =	{
		"HTH" : localeInfo.STAT_TOOLTIP_CON,
		"INT" : localeInfo.STAT_TOOLTIP_INT,
		"STR" : localeInfo.STAT_TOOLTIP_STR,
		"DEX" : localeInfo.STAT_TOOLTIP_DEX,
	}


	STAT_MINUS_DESCRIPTION = localeInfo.STAT_MINUS_DESCRIPTION

	def __init__(self):
		ui.ScriptWindow.__init__(self)
		self.state = "STATUS"
		self.isLoaded = 0
		self.interface = None

		self.toolTipSkill = 0
		self.lastUpdate3 = 0

		self.__Initialize()
		self.__LoadWindow()

		self.statusPlusCommandDict={
			"HTH" : "/stat ht",
			"INT" : "/stat iq",
			"STR" : "/stat st",
			"DEX" : "/stat dx",
		}

		self.statusMinusCommandDict={
			"HTH-" : "/stat- ht",
			"INT-" : "/stat- iq",
			"STR-" : "/stat- st",
			"DEX-" : "/stat- dx",
		}

	def __del__(self):
		ui.ScriptWindow.__del__(self)

	def __Initialize(self):
		self.refreshToolTip = 0
		self.curSelectedSkillGroup = 0
		self.canUseHorseSkill = -1

		self.toolTip = None
		self.toolTipJob = None
		self.toolTipAlignment = None
		self.toolTipSkill = None

		self.faceImage = None
		self.statusPlusLabel = None
		self.statusPlusValue = None
		self.activeSlot = None
		self.tabDict = None
		self.tabButtonDict = None
		self.pageDict = None
		self.titleBarDict = None
		self.statusPlusButtonDict = None
		self.statusMinusButtonDict = None

		self.skillPageDict = None
		self.questShowingStartIndex = 0
		self.questScrollBar = None
		self.questSlot = None
		self.questNameList = None
		self.questLastTimeList = None
		self.questLastCountList = None
		#REDDEV_NEW_QUEST_LISTING
		self.actualQuestList = {}
		self.additionalY = 0
		self.countersList = []
		self.timersList = []
		self.markedQuests = []
		#ENDOF_REDDEV_NEW_QUEST_LISTING
		self.skillGroupButton = ()

		self.activeSlot = None
		self.activeSkillPointValue = None
		self.supportSkillPointValue = None
		self.skillGroupButton1 = None
		self.skillGroupButton2 = None
		self.activeSkillGroupName = None

		self.guildNameSlot = None
		self.guildNameValue = None
		self.characterNameSlot = None
		self.characterNameValue = None

		self.emotionToolTip = None
		self.soloEmotionSlot = None
		self.dualEmotionSlot = None
		
		self.boardWindow = None
		#REDDEV_MULTIBONUS_SHOW
		self.actualSubPage = 0
		#ENDOF_REDDEV_MULTIBONUS

	def Show(self):
		self.__LoadWindow()

		ui.ScriptWindow.Show(self)

	def __LoadScript(self, fileName):
		pyScrLoader = ui.PythonScriptLoader()
		pyScrLoader.LoadScriptFile(self, fileName)

	def __BindObject(self):
		self.toolTip = uiToolTip.ToolTip()
		self.toolTipJob = uiToolTip.ToolTip()
		self.toolTipAlignment = uiToolTip.ToolTip(130)

		self.faceImage = self.GetChild("Face_Image")

		faceSlot=self.GetChild("Face_Slot")
		if 949 == app.GetDefaultCodePage():
			faceSlot.SAFE_SetStringEvent("MOUSE_OVER_IN", self.__ShowJobToolTip)
			faceSlot.SAFE_SetStringEvent("MOUSE_OVER_OUT", self.__HideJobToolTip)

		self.statusPlusLabel = self.GetChild("Status_Plus_Label")
		self.statusPlusValue = self.GetChild("Status_Plus_Value")

		self.characterNameSlot = self.GetChild("Character_Name_Slot")
		self.characterNameValue = self.GetChild("Character_Name")
		self.guildNameSlot = self.GetChild("Guild_Name_Slot")
		self.guildNameValue = self.GetChild("Guild_Name")
		self.characterNameSlot.SAFE_SetStringEvent("MOUSE_OVER_IN", self.__ShowAlignmentToolTip)
		self.characterNameSlot.SAFE_SetStringEvent("MOUSE_OVER_OUT", self.__HideAlignmentToolTip)

		self.activeSlot = self.GetChild("Skill_Active_Slot")
		self.activeSkillPointValue = self.GetChild("Active_Skill_Point_Value")
		self.supportSkillPointValue = self.GetChild("Support_Skill_Point_Value")
		self.skillGroupButton1 = self.GetChild("Skill_Group_Button_1")
		self.skillGroupButton2 = self.GetChild("Skill_Group_Button_2")
		self.activeSkillGroupName = self.GetChild("Active_Skill_Group_Name")

		self.tabDict = {
			"STATUS"	: self.GetChild("Tab_01"),
			"SKILL"		: self.GetChild("Tab_02"),
			"EMOTICON"	: self.GetChild("Tab_03"),
			"QUEST"		: self.GetChild("Tab_04"),
		}

		self.tabButtonDict = {
			"STATUS"	: self.GetChild("Tab_Button_01"),
			"SKILL"		: self.GetChild("Tab_Button_02"),
			"EMOTICON"	: self.GetChild("Tab_Button_03"),
			"QUEST"		: self.GetChild("Tab_Button_04")
		}

		self.pageDict = {
			"STATUS"	: self.GetChild("Character_Page"),
			"SKILL"		: self.GetChild("Skill_Page"),
			"EMOTICON"	: self.GetChild("Emoticon_Page"),
			"QUEST"		: self.GetChild("Quest_Page")
		}

		self.titleBarDict = {
			"STATUS"	: self.GetChild("Character_TitleBar"),
			"SKILL"		: self.GetChild("Skill_TitleBar"),
			"EMOTICON"	: self.GetChild("Emoticon_TitleBar"),
			"QUEST"		: self.GetChild("Quest_TitleBar")
		}

		self.statusPlusButtonDict = {
			"HTH"		: self.GetChild("HTH_Plus"),
			"INT"		: self.GetChild("INT_Plus"),
			"STR"		: self.GetChild("STR_Plus"),
			"DEX"		: self.GetChild("DEX_Plus"),
		}

		self.statusMinusButtonDict = {
			"HTH-"		: self.GetChild("HTH_Minus"),
			"INT-"		: self.GetChild("INT_Minus"),
			"STR-"		: self.GetChild("STR_Minus"),
			"DEX-"		: self.GetChild("DEX_Minus"),
		}

		self.skillPageDict = {
			"ACTIVE" : self.GetChild("Skill_Active_Slot"),
			"SUPPORT" : self.GetChild("Skill_ETC_Slot"),
			"HORSE" : self.GetChild("Skill_Active_Slot"),
		}

		self.skillPageStatDict = {
			"SUPPORT"	: player.SKILL_SUPPORT,
			"ACTIVE"	: player.SKILL_ACTIVE,
			"HORSE"		: player.SKILL_HORSE,
		}

		self.skillGroupButton = (
			self.GetChild("Skill_Group_Button_1"),
			self.GetChild("Skill_Group_Button_2"),
		)


		global SHOW_ONLY_ACTIVE_SKILL
		global HIDE_SUPPORT_SKILL_POINT
		if SHOW_ONLY_ACTIVE_SKILL or HIDE_SUPPORT_SKILL_POINT:
			self.GetChild("Support_Skill_Point_Label").Hide()

		self.soloEmotionSlot = self.GetChild("SoloEmotionSlot")
		self.dualEmotionSlot = self.GetChild("DualEmotionSlot")
		self.__SetEmotionSlot()

		self.questShowingStartIndex = 0
		self.questScrollBar = self.GetChild("Quest_ScrollBar")
		self.questScrollBar.SetScrollEvent(ui.__mem_func__(self.OnQuestScroll))
		# REDDEV_NEW_QUEST_LISTING
		#self.questSlot = self.GetChild("Quest_Slot")
		#for i in xrange(quest.QUEST_MAX_NUM):
		#	self.questSlot.HideSlotBaseImage(i)
		#	self.questSlot.SetCoverButton(i,\
		#									"d:/ymir work/ui/game/quest/slot_button_01.sub",\
		#									"d:/ymir work/ui/game/quest/slot_button_02.sub",\
		#									"d:/ymir work/ui/game/quest/slot_button_03.sub",\
		#									"d:/ymir work/ui/game/quest/slot_button_03.sub", True)
		#
		#self.questNameList = []
		#self.questLastTimeList = []
		#self.questLastCountList = []
		#for i in xrange(quest.QUEST_MAX_NUM):
		#	self.questNameList.append(self.GetChild("Quest_Name_0" + str(i)))
		#	self.questLastTimeList.append(self.GetChild("Quest_LastTime_0" + str(i)))
		#	self.questLastCountList.append(self.GetChild("Quest_LastCount_0" + str(i)))
		# ENDOF_REDDEV_NEW_QUEST_LISTING
		
		#REDDEV_MULTIBONUS
		self.subPageText01 = ui.TextLine()
		self.subPageText01.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText01.SetPackedFontColor(0xffffffff)
		self.subPageText01.SetParent(self.GetChild("Status_Extent"))
		self.subPageText01.SetPosition(11,35)
		
		self.subPageText02 = ui.TextLine()
		self.subPageText02.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText02.SetPackedFontColor(0xffffffff)
		self.subPageText02.SetParent(self.GetChild("Status_Extent"))
		self.subPageText02.SetPosition(11,33+23+2)
		
		self.subPageText03 = ui.TextLine()
		self.subPageText03.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText03.SetPackedFontColor(0xffffffff)
		self.subPageText03.SetParent(self.GetChild("Status_Extent"))
		self.subPageText03.SetPosition(11,33+46+2)
		
		self.subPageText04 = ui.TextLine()
		self.subPageText04.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText04.SetPackedFontColor(0xffffffff)
		self.subPageText04.SetParent(self.GetChild("Status_Extent"))
		self.subPageText04.SetPosition(128,35)
		
		self.subPageText05 = ui.TextLine()
		self.subPageText05.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText05.SetPackedFontColor(0xffffffff)
		self.subPageText05.SetParent(self.GetChild("Status_Extent"))
		self.subPageText05.SetPosition(128,33+23+2)
		
		self.subPageText06 = ui.TextLine()
		self.subPageText06.SetFontName(localeInfo.UI_DEF_FONT_BTN)
		self.subPageText06.SetPackedFontColor(0xffffffff)
		self.subPageText06.SetParent(self.GetChild("Status_Extent"))
		self.subPageText06.SetPosition(128,33+46+2)
		#ENDOF_REDDEV_MULTI_BONUS_SHOWER

	def __SetSkillSlotEvent(self):
		for skillPageValue in self.skillPageDict.itervalues():
			skillPageValue.SetSlotStyle(wndMgr.SLOT_STYLE_NONE)
			skillPageValue.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectSkill))
			skillPageValue.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot))
			skillPageValue.SetUnselectItemSlotEvent(ui.__mem_func__(self.ClickSkillSlot))
			skillPageValue.SetUseSlotEvent(ui.__mem_func__(self.ClickSkillSlot))
			skillPageValue.SetOverInItemEvent(ui.__mem_func__(self.OverInItem))
			skillPageValue.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem))
			skillPageValue.SetPressedSlotButtonEvent(ui.__mem_func__(self.OnPressedSlotButton))
			skillPageValue.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\
											"d:/ymir work/ui/game/windows/btn_plus_over.sub",\
											"d:/ymir work/ui/game/windows/btn_plus_down.sub")

	def __SetEmotionSlot(self):

		self.emotionToolTip = uiToolTip.ToolTip()

		for slot in (self.soloEmotionSlot, self.dualEmotionSlot):
			slot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE)
			slot.SetSelectItemSlotEvent(ui.__mem_func__(self.__SelectEmotion))
			slot.SetUnselectItemSlotEvent(ui.__mem_func__(self.__ClickEmotionSlot))
			slot.SetUseSlotEvent(ui.__mem_func__(self.__ClickEmotionSlot))
			slot.SetOverInItemEvent(ui.__mem_func__(self.__OverInEmotion))
			slot.SetOverOutItemEvent(ui.__mem_func__(self.__OverOutEmotion))
			slot.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\
											"d:/ymir work/ui/game/windows/btn_plus_over.sub",\
											"d:/ymir work/ui/game/windows/btn_plus_down.sub")

		for slotIdx, datadict in emotion.EMOTION_DICT.items():
			emotionIdx = slotIdx

			slot = self.soloEmotionSlot
			if slotIdx > 50:
				slot = self.dualEmotionSlot

			slot.SetEmotionSlot(slotIdx, emotionIdx)
			slot.SetCoverButton(slotIdx)

	def __SelectEmotion(self, slotIndex):
		if not slotIndex in emotion.EMOTION_DICT:
			return

		if app.IsPressed(app.DIK_LCONTROL):
			player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_EMOTION, slotIndex)
			return

		mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_EMOTION, slotIndex, slotIndex)

	def __ClickEmotionSlot(self, slotIndex):
		print "click emotion"
		if not slotIndex in emotion.EMOTION_DICT:
			return

		print "check acting"
		if player.IsActingEmotion():
			return
		
		command = emotion.EMOTION_DICT[slotIndex]["command"]
		print "command", command
		if self.lastUpdate3 < app.GetGlobalTime():
			self.lastUpdate3=app.GetGlobalTime()+5000 # 5 secunde 	
			if slotIndex > 50:
				vid = player.GetTargetVID()
	
				if 0 == vid or vid == player.GetMainCharacterIndex() or chr.IsNPC(vid) or chr.IsEnemy(vid):
					import chat
					chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.EMOTION_CHOOSE_ONE)
					return
	
				command += " " + chr.GetNameByVID(vid)
	
			print "send_command", command
			net.SendChatPacket(command)
			import chat
			chat.AppendChat(chat.CHAT_TYPE_INFO, "Asteapta 5 secunde pentru a folosi emotia din nou.")

	def ActEmotion(self, emotionIndex):
		self.__ClickEmotionSlot(emotionIndex)

	def __OverInEmotion(self, slotIndex):
		if self.emotionToolTip:

			if not slotIndex in emotion.EMOTION_DICT:
				return

			self.emotionToolTip.ClearToolTip()
			self.emotionToolTip.SetTitle(emotion.EMOTION_DICT[slotIndex]["name"])
			self.emotionToolTip.AlignHorizonalCenter()
			self.emotionToolTip.ShowToolTip()

	def __OverOutEmotion(self):
		if self.emotionToolTip:
			self.emotionToolTip.HideToolTip()

	def __BindEvent(self):
		for i in xrange(len(self.skillGroupButton)):
			self.skillGroupButton[i].SetEvent(lambda arg=i: self.__SelectSkillGroup(arg))

		self.RefreshQuest()
		self.__HideJobToolTip()

		for (tabKey, tabButton) in self.tabButtonDict.items():
			tabButton.SetEvent(ui.__mem_func__(self.__OnClickTabButton), tabKey)

		for (statusPlusKey, statusPlusButton) in self.statusPlusButtonDict.items():
			statusPlusButton.SAFE_SetEvent(self.__OnClickStatusPlusButton, statusPlusKey)
			statusPlusButton.ShowToolTip = lambda arg=statusPlusKey: self.__OverInStatButton(arg)
			statusPlusButton.HideToolTip = lambda arg=statusPlusKey: self.__OverOutStatButton()

		for (statusMinusKey, statusMinusButton) in self.statusMinusButtonDict.items():
			statusMinusButton.SAFE_SetEvent(self.__OnClickStatusMinusButton, statusMinusKey)
			statusMinusButton.ShowToolTip = lambda arg=statusMinusKey: self.__OverInStatMinusButton(arg)
			statusMinusButton.HideToolTip = lambda arg=statusMinusKey: self.__OverOutStatMinusButton()

		for titleBarValue in self.titleBarDict.itervalues():
			titleBarValue.SetCloseEvent(ui.__mem_func__(self.Hide))

		#REDDEV_NEW_QUEST_LISTING
		#self.questSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.__SelectQuest))
		#ENDOF_REDDEV_NEW_QUEST_LISTING
		
		#REDDEV_MULTI_BONUS_SHOWER
		for i in xrange(5):
			self.GetChild("SubPage"+str(i)).SetEvent(ui.__mem_func__(self.switchSubPage), i)
		
	def switchSubPage(self, num):
		for i in xrange(5):
			if i!=num:
				self.GetChild("SubPage"+str(i)).SetUp()
		if num==0:
			self.GetChild("Status_Extent_ItemList1").Show()
			self.GetChild("Status_Extent_ItemList2").Show()
			self.subPageText01.Hide()
			self.subPageText02.Hide()
			self.subPageText03.Hide()
			self.subPageText04.Hide()
			self.subPageText05.Hide()
			self.subPageText06.Hide()
		elif num==1:		
			self.GetChild("Status_Extent_ItemList1").Hide()
			self.GetChild("Status_Extent_ItemList2").Hide()
			self.subPageText01.SetText("Ap. sabie:")
			self.subPageText01.Show()
			self.subPageText02.SetText("Ap. 2maini:")
			self.subPageText02.Show()
			self.subPageText03.SetText("Ap. pumnal:")
			self.subPageText03.Show()
			self.subPageText04.SetText("Ap. sageti:")
			self.subPageText04.Show()
			self.subPageText05.SetText("Ap. evantai:")
			self.subPageText05.Show()
			self.subPageText06.SetText("Rez. magie:")
			self.subPageText06.Show()
		elif num==2:
			self.GetChild("Status_Extent_ItemList1").Hide()
			self.GetChild("Status_Extent_ItemList2").Hide()
			self.subPageText01.SetText("Vs. semi-om:")
			self.subPageText01.Show()
			self.subPageText02.SetText("Critica:")
			self.subPageText02.Show()
			self.subPageText03.SetText("Patrundere:")
			self.subPageText03.Show()
			self.subPageText04.SetText("Vs. monstrii:")
			self.subPageText04.Show()
			self.subPageText05.SetText("Naucire:")
			self.subPageText05.Show()
			self.subPageText06.SetText("Otravire:")
			self.subPageText06.Show()
		
		elif num==3:
			self.GetChild("Status_Extent_ItemList1").Hide()
			self.GetChild("Status_Extent_ItemList2").Hide()
			self.subPageText01.SetText("Anti razb:")
			self.subPageText01.Show()
			self.subPageText02.SetText("Anti ninja:")
			self.subPageText02.Show()
			self.subPageText03.SetText("Anti sura:")
			self.subPageText03.Show()
			self.subPageText04.SetText("Anti saman:")
			self.subPageText04.Show()
			self.subPageText05.SetText("Absorb. PV:")
			self.subPageText05.Show()
			self.subPageText06.SetText("Absorb. PM:")
			self.subPageText06.Show()
		
		elif num==4:
			self.GetChild("Status_Extent_ItemList1").Hide()
			self.GetChild("Status_Extent_ItemList2").Hide()
			self.subPageText01.SetText("Rez. razb:")
			self.subPageText01.Show()
			self.subPageText02.SetText("Rez. ninja:")
			self.subPageText02.Show()
			self.subPageText03.SetText("Rez. sura:")
			self.subPageText03.Show()
			self.subPageText04.SetText("Rez. saman:")
			self.subPageText04.Show()
			self.subPageText05.SetText("Blocare:")
			self.subPageText05.Show()
			self.subPageText06.SetText("Medie:")
			self.subPageText06.Show()
		
		if num < 0 or num > 4:
			num = 0
		self.actualSubPage = num
		self.RefreshStatus()
	#ENDOF_REDDEV_MULTI_BONUS_SHOWER

	def __LoadWindow(self):
		if self.isLoaded == 1:
			return

		self.isLoaded = 1

		try:
			if localeInfo.IsARABIC() or localeInfo.IsVIETNAM() or localeInfo.IsJAPAN():
				self.__LoadScript(uiScriptLocale.LOCALE_UISCRIPT_PATH + "CharacterWindow.py")
			else:
				self.__LoadScript("UIScript/CharacterWindow.py")

			self.__BindObject()
			self.__BindEvent()
		except:
			import exception
			exception.Abort("CharacterWindow.__LoadWindow")

		#self.tabButtonDict["EMOTICON"].Disable()
		self.SetState("STATUS")

	def Destroy(self):
		self.ClearDictionary()

		self.__Initialize()

	def Close(self):
		if 0 != self.toolTipSkill:
			self.toolTipSkill.Hide()

		self.Hide()

	def SetSkillToolTip(self, toolTipSkill):
		self.toolTipSkill = toolTipSkill

	def __OnClickStatusPlusButton(self, statusKey):
		try:
			statusPlusCommand=self.statusPlusCommandDict[statusKey]
			net.SendChatPacket(statusPlusCommand)
		except KeyError, msg:
			dbg.TraceError("CharacterWindow.__OnClickStatusPlusButton KeyError: %s", msg)

	def __OnClickStatusMinusButton(self, statusKey):
		try:
			statusMinusCommand=self.statusMinusCommandDict[statusKey]
			net.SendChatPacket(statusMinusCommand)
		except KeyError, msg:
			dbg.TraceError("CharacterWindow.__OnClickStatusMinusButton KeyError: %s", msg)


	def __OnClickTabButton(self, stateKey):
		self.SetState(stateKey)

	def SetState(self, stateKey):
		
		self.state = stateKey

		for (tabKey, tabButton) in self.tabButtonDict.items():
			if stateKey!=tabKey:
				tabButton.SetUp()

		for tabValue in self.tabDict.itervalues():
			tabValue.Hide()

		for pageValue in self.pageDict.itervalues():
			pageValue.Hide()

		for titleBarValue in self.titleBarDict.itervalues():
			titleBarValue.Hide()

		self.titleBarDict[stateKey].Show()
		self.tabDict[stateKey].Show()
		self.pageDict[stateKey].Show()
		
		#REDDEV_NEW_QUEST_LISTING
		if stateKey == 'QUEST':
			self.RefreshQuest()
		#ENDOF_REDDEV_NEW_QUEST_LISTING
		

	def GetState(self):
		return self.state

	def __GetTotalAtkText(self):
		minAtk=player.GetStatus(player.ATT_MIN)
		maxAtk=player.GetStatus(player.ATT_MAX)
		atkBonus=player.GetStatus(player.ATT_BONUS)
		attackerBonus=player.GetStatus(player.ATTACKER_BONUS)

		if minAtk==maxAtk:
			return "%d" % (minAtk+atkBonus+attackerBonus)
		else:
			return "%d-%d" % (minAtk+atkBonus+attackerBonus, maxAtk+atkBonus+attackerBonus)

	def __GetTotalMagAtkText(self):
		minMagAtk=player.GetStatus(player.MAG_ATT)+player.GetStatus(player.MIN_MAGIC_WEP)
		maxMagAtk=player.GetStatus(player.MAG_ATT)+player.GetStatus(player.MAX_MAGIC_WEP)

		if minMagAtk==maxMagAtk:
			return "%d" % (minMagAtk)
		else:
			return "%d-%d" % (minMagAtk, maxMagAtk)

	def __GetTotalDefText(self):
		defValue=player.GetStatus(player.DEF_GRADE)
		if constInfo.ADD_DEF_BONUS_ENABLE:
			defValue+=player.GetStatus(player.DEF_BONUS)
		return "%d" % (defValue)

	def RefreshStatus(self):
		if self.isLoaded==0:
			return

		try:
			self.GetChild("Level_Value").SetText(str(player.GetStatus(player.LEVEL)))
			self.GetChild("Exp_Value").SetText(str(unsigned32(player.GetEXP())))
			self.GetChild("RestExp_Value").SetText(str(unsigned32(player.GetStatus(player.NEXT_EXP)) - unsigned32(player.GetStatus(player.EXP))))
			self.GetChild("HP_Value").SetText(str(player.GetStatus(player.HP)) + '/' + str(player.GetStatus(player.MAX_HP)))
			self.GetChild("SP_Value").SetText(str(player.GetStatus(player.SP)) + '/' + str(player.GetStatus(player.MAX_SP)))

			self.GetChild("STR_Value").SetText(str(player.GetStatus(player.ST)))
			self.GetChild("DEX_Value").SetText(str(player.GetStatus(player.DX)))
			self.GetChild("HTH_Value").SetText(str(player.GetStatus(player.HT)))
			self.GetChild("INT_Value").SetText(str(player.GetStatus(player.IQ)))

			self.GetChild("ATT_Value").SetText(self.__GetTotalAtkText())
			self.GetChild("DEF_Value").SetText(self.__GetTotalDefText())
			
			#REDDEV_MULTI_BONUS_SHOWER
			#self.GetChild("MATT_Value").SetText(self.__GetTotalMagAtkText())
			#self.GetChild("MATT_Value").SetText(str(player.GetStatus(player.MAG_ATT)))

			#self.GetChild("MDEF_Value").SetText(str(player.GetStatus(player.MAG_DEF)))
			#self.GetChild("ASPD_Value").SetText(str(player.GetStatus(player.ATT_SPEED)))
			#self.GetChild("MSPD_Value").SetText(str(player.GetStatus(player.MOVING_SPEED)))
			#self.GetChild("CSPD_Value").SetText(str(player.GetStatus(player.CASTING_SPEED)))
			#self.GetChild("ER_Value").SetText(str(player.GetStatus(player.EVADE_RATE)))
			
			if self.actualSubPage == 0:
				self.GetChild("MATT_Value").SetText(self.__GetTotalMagAtkText())
				self.GetChild("MDEF_Value").SetText(str(player.GetStatus(player.MAG_DEF)))
				self.GetChild("ASPD_Value").SetText(str(player.GetStatus(player.ATT_SPEED)))
				self.GetChild("MSPD_Value").SetText(str(player.GetStatus(player.MOVING_SPEED)))
				self.GetChild("CSPD_Value").SetText(str(player.GetStatus(player.CASTING_SPEED)))
				self.GetChild("ER_Value").SetText(str(player.GetStatus(player.EVADE_RATE)))
			elif self.actualSubPage == 1:
				self.GetChild("MSPD_Value").SetText(str(player.GetStatus(69)) + str("%")) #Resist sword
				self.GetChild("ASPD_Value").SetText(str(player.GetStatus(70)) + str("%")) #Resist 2hand
				self.GetChild("CSPD_Value").SetText(str(player.GetStatus(71)) + str("%")) #Resist dagger
				self.GetChild("MATT_Value").SetText(str(player.GetStatus(74)) + str("%")) #Resist bow
				self.GetChild("MDEF_Value").SetText(str(player.GetStatus(73)) + str("%")) #Resist fan
				self.GetChild("ER_Value").SetText(str(player.GetStatus(77)) + str("%")) #Resist magic
			elif self.actualSubPage == 2:
				self.GetChild("MSPD_Value").SetText(str(player.GetStatus(43)) + str("%")) #Anti semi-om
				self.GetChild("ASPD_Value").SetText(str(player.GetStatus(40)) + str("%")) #Critical chance
				self.GetChild("CSPD_Value").SetText(str(player.GetStatus(41)) + str("%")) #Penetrate chance
				self.GetChild("MATT_Value").SetText(str(player.GetStatus(53)) + str("%")) #Anti mobs
				self.GetChild("MDEF_Value").SetText(str(player.GetStatus(38)) + str("%")) #Stun chance
				self.GetChild("ER_Value").SetText(str(player.GetStatus(37)) + str("%")) #Poison chance
			
			elif self.actualSubPage == 3:
				self.GetChild("MSPD_Value").SetText(str(player.GetStatus(54)) + str("%")) #Anti Warrior
				self.GetChild("ASPD_Value").SetText(str(player.GetStatus(55)) + str("%")) #Anti Ninja
				self.GetChild("CSPD_Value").SetText(str(player.GetStatus(56)) + str("%")) #Anti sura
				self.GetChild("MATT_Value").SetText(str(player.GetStatus(57)) + str("%")) #Anti shaman
				self.GetChild("MDEF_Value").SetText(str(player.GetStatus(63)) + str("%")) #HP Steal
				self.GetChild("ER_Value").SetText(str(player.GetStatus(64)) + str("%")) #SP Steal
				
			elif self.actualSubPage == 4:
				self.GetChild("MSPD_Value").SetText(str(player.GetStatus(59)) + str("%")) #Res warrior
				self.GetChild("ASPD_Value").SetText(str(player.GetStatus(60)) + str("%")) #res Ninja
				self.GetChild("CSPD_Value").SetText(str(player.GetStatus(61)) + str("%")) #res sura
				self.GetChild("MATT_Value").SetText(str(player.GetStatus(62)) + str("%")) #res shaman
				self.GetChild("MDEF_Value").SetText(str(player.GetStatus(67)) + str("%")) #Block
				self.GetChild("ER_Value").SetText(str(player.GetStatus(72)) + str("%")) #Paguba Medie
			else:
				pass
			#ENDOF_REDDEV_MULTI_BONUS_SHOWER

		except:
			#import exception
			#exception.Abort("CharacterWindow.RefreshStatus.BindObject")
			## 게임이 튕겨 버림
			pass

		self.__RefreshStatusPlusButtonList()
		self.__RefreshStatusMinusButtonList()
		self.RefreshAlignment()

		if self.refreshToolTip:
			self.refreshToolTip()

	def __RefreshStatusPlusButtonList(self):
		if self.isLoaded==0:
			return

		statusPlusPoint=player.GetStatus(player.STAT)

		if statusPlusPoint>0:
			self.statusPlusValue.SetText(str(statusPlusPoint))
			self.statusPlusLabel.Show()
			self.ShowStatusPlusButtonList()
		else:
			self.statusPlusValue.SetText(str(0))
			self.statusPlusLabel.Hide()
			self.HideStatusPlusButtonList()

	def __RefreshStatusMinusButtonList(self):
		if self.isLoaded==0:
			return

		statusMinusPoint=self.__GetStatMinusPoint()

		if statusMinusPoint>0:
			self.__ShowStatusMinusButtonList()
		else:
			self.__HideStatusMinusButtonList()

	def RefreshAlignment(self):
		point, grade = player.GetAlignmentData()

		import colorInfo
		COLOR_DICT = {	0 : colorInfo.TITLE_RGB_GOOD_4,
						1 : colorInfo.TITLE_RGB_GOOD_3,
						2 : colorInfo.TITLE_RGB_GOOD_2,
						3 : colorInfo.TITLE_RGB_GOOD_1,
						4 : colorInfo.TITLE_RGB_NORMAL,
						5 : colorInfo.TITLE_RGB_EVIL_1,
						6 : colorInfo.TITLE_RGB_EVIL_2,
						7 : colorInfo.TITLE_RGB_EVIL_3,
						8 : colorInfo.TITLE_RGB_EVIL_4, }
		colorList = COLOR_DICT.get(grade, colorInfo.TITLE_RGB_NORMAL)
		gradeColor = ui.GenerateColor(colorList[0], colorList[1], colorList[2])

		self.toolTipAlignment.ClearToolTip()
		self.toolTipAlignment.AutoAppendTextLine(localeInfo.TITLE_NAME_LIST[grade], gradeColor)
		self.toolTipAlignment.AutoAppendTextLine(localeInfo.ALIGNMENT_NAME + str(point))
		self.toolTipAlignment.AlignHorizonalCenter()
			

	def __ShowStatusMinusButtonList(self):
		for (stateMinusKey, statusMinusButton) in self.statusMinusButtonDict.items():
			statusMinusButton.Show()

	def __HideStatusMinusButtonList(self):
		for (stateMinusKey, statusMinusButton) in self.statusMinusButtonDict.items():
			statusMinusButton.Hide()

	def ShowStatusPlusButtonList(self):
		for (statePlusKey, statusPlusButton) in self.statusPlusButtonDict.items():
			statusPlusButton.Show()

	def HideStatusPlusButtonList(self):
		for (statePlusKey, statusPlusButton) in self.statusPlusButtonDict.items():
			statusPlusButton.Hide()

	def SelectSkill(self, skillSlotIndex):

		mouseController = mouseModule.mouseController

		if False == mouseController.isAttached():

			srcSlotIndex = self.__RealSkillSlotToSourceSlot(skillSlotIndex)
			selectedSkillIndex = player.GetSkillIndex(srcSlotIndex)

			if skill.CanUseSkill(selectedSkillIndex):

				if app.IsPressed(app.DIK_LCONTROL):

					player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_SKILL, srcSlotIndex)
					return

				mouseController.AttachObject(self, player.SLOT_TYPE_SKILL, srcSlotIndex, selectedSkillIndex)

		else:

			mouseController.DeattachObject()

	def SelectEmptySlot(self, SlotIndex):
		mouseModule.mouseController.DeattachObject()

	## ToolTip
	def OverInItem(self, slotNumber):
		if mouseModule.mouseController.isAttached():
			return

		if 0 == self.toolTipSkill:
			return

		srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotNumber)
		skillIndex = player.GetSkillIndex(srcSlotIndex)
		skillLevel = player.GetSkillLevel(srcSlotIndex)
		skillGrade = player.GetSkillGrade(srcSlotIndex)
		skillType = skill.GetSkillType(skillIndex)

		## ACTIVE
		if skill.SKILL_TYPE_ACTIVE == skillType:
			overInSkillGrade = self.__GetSkillGradeFromSlot(slotNumber)

			if overInSkillGrade == skill.SKILL_GRADE_COUNT-1 and skillGrade == skill.SKILL_GRADE_COUNT:
				self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, skillGrade, skillLevel)
			elif overInSkillGrade == skillGrade:
				if app.ENABLE_SKILLS_LEVEL_OVER_P and skillGrade == 2:
					self.toolTipSkill.SetSkillOnlyName(srcSlotIndex, skillIndex, overInSkillGrade + 1)
				else:
					self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, overInSkillGrade, skillLevel)
			elif app.ENABLE_SKILLS_LEVEL_OVER_P and overInSkillGrade == skill.SKILL_GRADE_COUNT-2 and skillGrade >= skill.SKILL_GRADE_COUNT-1:
				self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, skillGrade, skillLevel)
			else:
				if app.ENABLE_SKILLS_LEVEL_OVER_P and overInSkillGrade == 1 and skillGrade == 2:
					self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, overInSkillGrade + 1, skillLevel)
				elif app.ENABLE_SKILLS_LEVEL_OVER_P and overInSkillGrade == 2 and skillGrade < 3:
					self.toolTipSkill.SetSkillOnlyName(srcSlotIndex, skillIndex, overInSkillGrade + 1)
				else:
					self.toolTipSkill.SetSkillOnlyName(srcSlotIndex, skillIndex, overInSkillGrade)
		else:
			self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, skillGrade, skillLevel)

	def OverOutItem(self):
		if 0 != self.toolTipSkill:
			self.toolTipSkill.HideToolTip()

	## Quest
	def __SelectQuest(self, slotIndex):
		questIndex = quest.GetQuestIndex(self.questShowingStartIndex+slotIndex)

		#REDDEV_NEW_QUEST_LISTING
		if not questIndex in self.markedQuests:
			self.markedQuests.append(questIndex)

		import event
		#event.QuestButtonClick(-2147483648 + questIndex)
		event.QuestButtonClick(questIndex)
		#ENDOF_REDDEV_NEW_QUEST_LISTING

	''' REDDEV_NEW_QUEST_LISTING
	def RefreshQuest(self):

		if self.isLoaded==0:
			return

		questCount = quest.GetQuestCount()
		questRange = range(quest.QUEST_MAX_NUM)

		if questCount > quest.QUEST_MAX_NUM:
			self.questScrollBar.Show()
		else:
			self.questScrollBar.Hide()

		for i in questRange[:questCount]:
			(questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(self.questShowingStartIndex+i)

			self.questNameList[i].SetText(questName)
			self.questNameList[i].Show()
			self.questLastCountList[i].Show()
			self.questLastTimeList[i].Show()

			if len(questCounterName) > 0:
				self.questLastCountList[i].SetText("%s : %d" % (questCounterName, questCounterValue))
			else:
				self.questLastCountList[i].SetText("")

			## Icon
			self.questSlot.SetSlot(i, i, 1, 1, questIcon)

		for i in questRange[questCount:]:
			self.questNameList[i].Hide()
			self.questLastTimeList[i].Hide()
			self.questLastCountList[i].Hide()
			self.questSlot.ClearSlot(i)
			self.questSlot.HideSlotBaseImage(i)

		self.__UpdateQuestClock()

	def __UpdateQuestClock(self):
		if "QUEST" == self.state:
			# QUEST_LIMIT_COUNT_BUG_FIX
			for i in xrange(min(quest.GetQuestCount(), quest.QUEST_MAX_NUM)):
			# END_OF_QUEST_LIMIT_COUNT_BUG_FIX
				(lastName, lastTime) = quest.GetQuestLastTime(i)

				clockText = localeInfo.QUEST_UNLIMITED_TIME
				if len(lastName) > 0:

					if lastTime <= 0:
						clockText = localeInfo.QUEST_TIMEOVER

					else:
						questLastMinute = lastTime / 60
						questLastSecond = lastTime % 60

						clockText = lastName + " : "

						if questLastMinute > 0:
							clockText += str(questLastMinute) + localeInfo.QUEST_MIN
							if questLastSecond > 0:
								clockText += " "

						if questLastSecond > 0:
							clockText += str(questLastSecond) + localeInfo.QUEST_SEC

				self.questLastTimeList[i].SetText(clockText)
	''' #ENDOF_REDDEV_NEW_QUEST_LISTING
	
	#REDDEV_NEW_QUEST_LISTING
	def RefreshQuest(self):

		if self.isLoaded==0:
			return
		
		self.actualQuestList = {}
		for i in xrange(quest.QUEST_MAX_NUM):
			try:
				self.Pula[i].Hide()
			except:
				pass
		self.countersList = []
		self.timersList = []
		
		questCount = quest.GetQuestCount()
		questRange = range(quest.QUEST_MAX_NUM)
		
		page = self.GetChild("Quest_Page")
		

		if questCount > quest.QUEST_MAX_NUM:
			self.questScrollBar.Show()
		else:
			self.questScrollBar.Hide()
			
		self.GetChild("Quest_Title").SetTextAlignLeft("Misiuni (" + str(questCount) + ")")
		actualList = quest.QUEST_MAX_NUM
		self.additionalY = 0
		for i in questRange[:questCount]:
			if i >= actualList:
				pass
			else:
				(questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(self.questShowingStartIndex+i)
				(lastName, lastTime) = quest.GetQuestLastTime(self.questShowingStartIndex+i)
				
				yPos = 25 + i * 20 + self.additionalY * 14
				questSlot = ui.ListBar()
				questSlot.SetParent(page)
				questSlot.MakeListBar(180, 1)
				questSlot.SetWidth(180)
				if quest.GetQuestIndex(self.questShowingStartIndex+i) in self.markedQuests:
					questSlot.OnClickEvent()
				questSlot.SetPosition(10, yPos)
				if questName[0] == "*":
					questSlot.SetTextAlignLeft(questName[1:])
					questSlot.SetTextColor(0xff85beea)
				elif questName[0] == "!":
					questSlot.SetTextAlignLeft(questName[1:])
				elif questName[0] == "+":
					questSlot.SetTextAlignLeft(questName[1:])
					questSlot.SetTextColor(0xffd760ff)
				else:
					questSlot.SetTextAlignLeft(questName)
				questSlot.SetEvent(ui.__mem_func__(self.__SelectQuest), i)
				self.actualQuestList[i] = questSlot
				self.actualQuestList[i].Show()
				hasCounter = False
				if len(questCounterName) > 0:
					targetsRemain = ui.TextLine()
					targetsRemain.SetParent(page)
					targetsRemain.SetText("%s: %d" % (questCounterName, questCounterValue))
					targetsRemain.SetPosition(45, yPos+20)
					targetsRemain.Show()
					self.countersList.append(targetsRemain)
					self.additionalY += 1
					actualList -= 1
					hasCounter = True
				
				if len(lastName) > 0:

					if lastTime <= 0:
						clockText = localeInfo.QUEST_TIMEOVER

					else:
						questLastMinute = lastTime / 60
						questLastSecond = lastTime % 60

						clockText = lastName + ": "

						if questLastMinute > 0:
							clockText += str(questLastMinute) + localeInfo.QUEST_MIN
							if questLastSecond > 0:
								clockText += " "

						if questLastSecond > 0:
							clockText += str(questLastSecond) + localeInfo.QUEST_SEC
							
					clock = ui.TextLine()
					clock.SetParent(page)
					clock.SetPosition(45, yPos+20 + int(hasCounter)*14)
					clock.SetText(clockText)
					clock.SetProperty("idx", self.questShowingStartIndex+i)
					clock.Show()
					self.timersList.append(clock)
					self.additionalY += 1
					actualList -= 1

		self.__UpdateQuestClock()

	def __UpdateQuestClock(self):
		if "QUEST" == self.state:	
			for clock in self.timersList:
				if not clock.GetProperty("idx"):
					print "Invalid clock property"
					return
				
				(lastName, lastTime) = quest.GetQuestLastTime(clock.GetProperty("idx"))

				clockText = localeInfo.QUEST_UNLIMITED_TIME
				if len(lastName) > 0:

					if lastTime <= 0:
						clockText = localeInfo.QUEST_TIMEOVER

					else:
						questLastMinute = lastTime / 60
						questLastSecond = lastTime % 60

						clockText = lastName + ": "

						if questLastMinute > 0:
							clockText += str(questLastMinute) + localeInfo.QUEST_MIN
							if questLastSecond > 0:
								clockText += " "

						if questLastSecond > 0:
							clockText += str(questLastSecond) + localeInfo.QUEST_SEC

					clock.SetText(clockText)
	#ENDOF_REDDEV_NEW_QUEST_LISTING
	
	def __GetStatMinusPoint(self):
		POINT_STAT_RESET_COUNT = 112
		return player.GetStatus(POINT_STAT_RESET_COUNT)

	def __OverInStatMinusButton(self, stat):
		try:
			self.__ShowStatToolTip(self.STAT_MINUS_DESCRIPTION[stat] % self.__GetStatMinusPoint())
		except KeyError:
			pass

		self.refreshToolTip = lambda arg=stat: self.__OverInStatMinusButton(arg)

	def __OverOutStatMinusButton(self):
		self.__HideStatToolTip()
		self.refreshToolTip = 0

	def __OverInStatButton(self, stat):
		try:
			self.__ShowStatToolTip(self.STAT_DESCRIPTION[stat])
		except KeyError:
			pass

	def __OverOutStatButton(self):
		self.__HideStatToolTip()

	def __ShowStatToolTip(self, statDesc):
		self.toolTip.ClearToolTip()
		self.toolTip.AppendTextLine(statDesc)
		self.toolTip.Show()

	def __HideStatToolTip(self):
		self.toolTip.Hide()

	def OnPressEscapeKey(self):
		self.Close()
		return True

	def OnUpdate(self):
		self.__UpdateQuestClock()

	## Skill Process
	def __RefreshSkillPage(self, name, slotCount):
		global SHOW_LIMIT_SUPPORT_SKILL_LIST
		skillPage = self.skillPageDict[name]
		startSlotIndex = skillPage.GetStartIndex()
		if "ACTIVE" == name:
			if self.PAGE_HORSE == self.curSelectedSkillGroup:
				startSlotIndex += slotCount

		getSkillType=skill.GetSkillType
		getSkillIndex=player.GetSkillIndex
		getSkillGrade=player.GetSkillGrade
		getSkillLevel=player.GetSkillLevel
		getSkillLevelUpPoint=skill.GetSkillLevelUpPoint
		getSkillMaxLevel=skill.GetSkillMaxLevel

		if app.ENABLE_SKILLS_LEVEL_OVER_P:
			refresh = 0

		for i in xrange(slotCount+1):

			slotIndex = i + startSlotIndex
			skillIndex = getSkillIndex(slotIndex)
			if not app.ENABLE_SKILLS_LEVEL_OVER_P:
				for j in xrange(skill.SKILL_GRADE_COUNT):
					skillPage.ClearSlot(self.__GetRealSkillSlot(j, i))
			else:
				if not refresh and skillIndex >= 137 and skillIndex <= 140:
					for w in xrange(slotCount + 1):
						for q in xrange(skill.SKILL_GRADE_COUNT):
							skillPage.ClearSlot(self.__GetRealSkillSlot(q, w))
					
					refresh = 1
			
			if app.ENABLE_SKILLS_LEVEL_OVER_P:
				if slotIndex == 7 or slotIndex == 8:
					for j in xrange(skill.SKILL_GRADE_COUNT):
						skillPage.ClearSlot(self.__GetRealSkillSlot(j, slotIndex))

			if 0 == skillIndex:
				continue

			skillGrade = getSkillGrade(slotIndex)
			skillLevel = getSkillLevel(slotIndex)
			skillType = getSkillType(skillIndex)

			if player.SKILL_INDEX_RIDING == skillIndex:
				if app.ENABLE_SKILLS_LEVEL_OVER_P:
					skGrade = 0
					if skillLevel >= 11 and skillLevel < 20:
						skGrade = 1
					elif skillGrade == 1:
						skGrade = 2

				if 1 == skillGrade:
					skillLevel += 19
				elif 2 == skillGrade:
					skillLevel += 29
				elif 3 == skillGrade:
					skillLevel = 40

				if app.ENABLE_SKILLS_LEVEL_OVER_P:
					skGr = max(skillLevel - 1, 0)
					skGr = skGrade
					skillPage.SetSkillSlotNew(slotIndex, skillIndex, skGr, skillLevel)
				else:
					skillPage.SetSkillSlotNew(slotIndex, skillIndex, max(skillLevel-1, 0), skillLevel)

				skillPage.SetSlotCount(slotIndex, skillLevel)

			## ACTIVE
			elif skill.SKILL_TYPE_ACTIVE == skillType:
				for j in xrange(skill.SKILL_GRADE_COUNT):
					if app.ENABLE_SKILLS_LEVEL_OVER_P:
						if j == 2 and skillGrade == 1:
							continue

					realSlotIndex = self.__GetRealSkillSlot(j, slotIndex)
					skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, j, skillLevel)
					skillPage.SetCoverButton(realSlotIndex)

					if (skillGrade == skill.SKILL_GRADE_COUNT) and j == (skill.SKILL_GRADE_COUNT-1):
						skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel)
					elif (not self.__CanUseSkillNow()) or (skillGrade != j):
						if app.ENABLE_SKILLS_LEVEL_OVER_P:
							if j != 2 and skillGrade != 2:
								skillPage.ClearSlot(realSlotIndex)
								skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, j, skillLevel)
								skillPage.SetCoverButton(realSlotIndex)
							elif skillGrade == 2 and j >= 3:
								skillPage.ClearSlot(realSlotIndex)
								skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, j, skillLevel)
								skillPage.SetCoverButton(realSlotIndex)

						skillPage.SetSlotCount(realSlotIndex, 0)
						skillPage.DisableCoverButton(realSlotIndex)
					else:
						skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel)
			else:
				if not SHOW_LIMIT_SUPPORT_SKILL_LIST or skillIndex in SHOW_LIMIT_SUPPORT_SKILL_LIST:
					realSlotIndex = self.__GetETCSkillRealSlotIndex(slotIndex)
					skillPage.SetSkillSlot(realSlotIndex, skillIndex, skillLevel)
					skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel)
					if skill.CanUseSkill(skillIndex):
						skillPage.SetCoverButton(realSlotIndex)

			skillPage.RefreshSlot()

	def RefreshSkill(self):

		if self.isLoaded==0:
			return

		if self.__IsChangedHorseRidingSkillLevel():
			self.RefreshCharacter()
			return


		global SHOW_ONLY_ACTIVE_SKILL
		if SHOW_ONLY_ACTIVE_SKILL:
			self.__RefreshSkillPage("ACTIVE", self.ACTIVE_PAGE_SLOT_COUNT)
		else:
			self.__RefreshSkillPage("ACTIVE", self.ACTIVE_PAGE_SLOT_COUNT)
			self.__RefreshSkillPage("SUPPORT", self.SUPPORT_PAGE_SLOT_COUNT)

		self.RefreshSkillPlusButtonList()

	def CanShowPlusButton(self, skillIndex, skillLevel, curStatPoint):

		## 스킬이 있으면
		if 0 == skillIndex:
			return False

		## 레벨업 조건을 만족한다면
		if not skill.CanLevelUpSkill(skillIndex, skillLevel):
			return False

		return True

	def __RefreshSkillPlusButton(self, name):
		global HIDE_SUPPORT_SKILL_POINT
		if HIDE_SUPPORT_SKILL_POINT and "SUPPORT" == name:
			return

		slotWindow = self.skillPageDict[name]
		slotWindow.HideAllSlotButton()

		slotStatType = self.skillPageStatDict[name]
		if 0 == slotStatType:
			return

		statPoint = player.GetStatus(slotStatType)
		startSlotIndex = slotWindow.GetStartIndex()
		if "HORSE" == name:
			startSlotIndex += self.ACTIVE_PAGE_SLOT_COUNT

		if statPoint > 0:
			for i in xrange(self.PAGE_SLOT_COUNT):
				slotIndex = i + startSlotIndex
				skillIndex = player.GetSkillIndex(slotIndex)
				skillGrade = player.GetSkillGrade(slotIndex)
				skillLevel = player.GetSkillLevel(slotIndex)

				if skillIndex == 0:
					continue
				if skillGrade != 0:
					continue

				if name == "HORSE":
					if player.GetStatus(player.LEVEL) >= skill.GetSkillLevelLimit(skillIndex):
						if skillLevel < 20:
							slotWindow.ShowSlotButton(self.__GetETCSkillRealSlotIndex(slotIndex))

				else:
					if "SUPPORT" == name:
						if not SHOW_LIMIT_SUPPORT_SKILL_LIST or skillIndex in SHOW_LIMIT_SUPPORT_SKILL_LIST:
							if self.CanShowPlusButton(skillIndex, skillLevel, statPoint):
								slotWindow.ShowSlotButton(slotIndex)
					else:
						if self.CanShowPlusButton(skillIndex, skillLevel, statPoint):
							slotWindow.ShowSlotButton(slotIndex)


	def RefreshSkillPlusButtonList(self):

		if self.isLoaded==0:
			return

		self.RefreshSkillPlusPointLabel()

		if not self.__CanUseSkillNow():
			return

		try:
			if self.PAGE_HORSE == self.curSelectedSkillGroup:
				self.__RefreshSkillPlusButton("HORSE")
			else:
				self.__RefreshSkillPlusButton("ACTIVE")

			self.__RefreshSkillPlusButton("SUPPORT")

		except:
			import exception
			exception.Abort("CharacterWindow.RefreshSkillPlusButtonList.BindObject")

	def RefreshSkillPlusPointLabel(self):
		if self.isLoaded==0:
			return

		if self.PAGE_HORSE == self.curSelectedSkillGroup:
			activeStatPoint = player.GetStatus(player.SKILL_HORSE)
			self.activeSkillPointValue.SetText(str(activeStatPoint))

		else:
			activeStatPoint = player.GetStatus(player.SKILL_ACTIVE)
			self.activeSkillPointValue.SetText(str(activeStatPoint))

		supportStatPoint = max(0, player.GetStatus(player.SKILL_SUPPORT))
		self.supportSkillPointValue.SetText(str(supportStatPoint))

	## Skill Level Up Button
	def OnPressedSlotButton(self, slotNumber):
		srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotNumber)

		skillIndex = player.GetSkillIndex(srcSlotIndex)
		curLevel = player.GetSkillLevel(srcSlotIndex)
		maxLevel = skill.GetSkillMaxLevel(skillIndex)

		net.SendChatPacket("/skillup " + str(skillIndex))

	## Use Skill
	def ClickSkillSlot(self, slotIndex):

		srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotIndex)
		skillIndex = player.GetSkillIndex(srcSlotIndex)
		skillType = skill.GetSkillType(skillIndex)

		if not self.__CanUseSkillNow():
			if skill.SKILL_TYPE_ACTIVE == skillType:
				return

		for slotWindow in self.skillPageDict.values():
			if slotWindow.HasSlot(slotIndex):
				if skill.CanUseSkill(skillIndex):
					player.ClickSkillSlot(srcSlotIndex)
					return

		mouseModule.mouseController.DeattachObject()

	## FIXME : 스킬을 사용했을때 슬롯 번호를 가지고 해당 슬롯을 찾아서 업데이트 한다.
	##         매우 불합리. 구조 자체를 개선해야 할듯.
	def OnUseSkill(self, slotIndex, coolTime):

		skillIndex = player.GetSkillIndex(slotIndex)
		skillType = skill.GetSkillType(skillIndex)

		## ACTIVE
		if skill.SKILL_TYPE_ACTIVE == skillType:
			skillGrade = player.GetSkillGrade(slotIndex)
			slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex)
		## ETC
		else:
			slotIndex = self.__GetETCSkillRealSlotIndex(slotIndex)

		for slotWindow in self.skillPageDict.values():
			if slotWindow.HasSlot(slotIndex):
				slotWindow.SetSlotCoolTime(slotIndex, coolTime)
				return

	def OnActivateSkill(self, slotIndex):
		skillGrade = player.GetSkillGrade(slotIndex)
		slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex)
		for slotWindow in self.skillPageDict.values():
			if slotWindow.HasSlot(slotIndex):
				if app.ENABLE_SASH_SYSTEM:
					slotWindow.ActivateSlotOld(slotIndex)
				else:
					slotWindow.ActivateSlot(slotIndex)
				
				return

	def OnDeactivateSkill(self, slotIndex):
		skillGrade = player.GetSkillGrade(slotIndex)
		slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex)
		for slotWindow in self.skillPageDict.values():
			if slotWindow.HasSlot(slotIndex):
				if app.ENABLE_SASH_SYSTEM:
					slotWindow.DeactivateSlotOld(slotIndex)
				else:
					slotWindow.DeactivateSlot(slotIndex)
				
				return

	def __ShowJobToolTip(self):
		self.toolTipJob.ShowToolTip()

	def __HideJobToolTip(self):
		self.toolTipJob.HideToolTip()

	def __SetJobText(self, mainJob, subJob):
		if player.GetStatus(player.LEVEL)<5:
			subJob=0

		if 949 == app.GetDefaultCodePage():
			self.toolTipJob.ClearToolTip()

			try:
				jobInfoTitle=localeInfo.JOBINFO_TITLE[mainJob][subJob]
				jobInfoData=localeInfo.JOBINFO_DATA_LIST[mainJob][subJob]
			except IndexError:
				print "uiCharacter.CharacterWindow.__SetJobText(mainJob=%d, subJob=%d)" % (mainJob, subJob)
				return

			self.toolTipJob.AutoAppendTextLine(jobInfoTitle)
			self.toolTipJob.AppendSpace(5)

			for jobInfoDataLine in jobInfoData:
				self.toolTipJob.AutoAppendTextLine(jobInfoDataLine)

			self.toolTipJob.AlignHorizonalCenter()

	def __ShowAlignmentToolTip(self):
		self.toolTipAlignment.ShowToolTip()

	def __HideAlignmentToolTip(self):
		self.toolTipAlignment.HideToolTip()

	def RefreshCharacter(self):

		if self.isLoaded==0:
			return

		## Name
		try:
			characterName = player.GetName()
			guildName = player.GetGuildName()
			self.characterNameValue.SetText(characterName)
			self.guildNameValue.SetText(guildName)
			if not guildName:
				if localeInfo.IsARABIC():
					self.characterNameSlot.SetPosition(190, 34)
				else:
					self.characterNameSlot.SetPosition(109, 34)

				self.guildNameSlot.Hide()
			else:
				if localeInfo.IsJAPAN():
					self.characterNameSlot.SetPosition(143, 34)
				else:
					self.characterNameSlot.SetPosition(153, 34)
				self.guildNameSlot.Show()
		except:
			import exception
			exception.Abort("CharacterWindow.RefreshCharacter.BindObject")

		race = net.GetMainActorRace()
		group = net.GetMainActorSkillGroup()
		empire = net.GetMainActorEmpire()

		## Job Text
		job = chr.RaceToJob(race)
		self.__SetJobText(job, group)

		## FaceImage
		try:
			faceImageName = FACE_IMAGE_DICT[race]

			try:
				self.faceImage.LoadImage(faceImageName)
			except:
				print "CharacterWindow.RefreshCharacter(race=%d, faceImageName=%s)" % (race, faceImageName)
				self.faceImage.Hide()

		except KeyError:
			self.faceImage.Hide()

		## GroupName
		self.__SetSkillGroupName(race, group)

		## Skill
		if 0 == group:
			self.__SelectSkillGroup(0)

		else:
			self.__SetSkillSlotData(race, group, empire)

			if self.__CanUseHorseSkill():
				self.__SelectSkillGroup(0)

	def __SetSkillGroupName(self, race, group):

		job = chr.RaceToJob(race)

		if not self.SKILL_GROUP_NAME_DICT.has_key(job):
			return

		nameList = self.SKILL_GROUP_NAME_DICT[job]

		if 0 == group:
			self.skillGroupButton1.SetText(nameList[1])
			self.skillGroupButton2.SetText(nameList[2])
			self.skillGroupButton1.Show()
			self.skillGroupButton2.Show()
			self.activeSkillGroupName.Hide()

		else:

			if self.__CanUseHorseSkill():
				self.activeSkillGroupName.Hide()
				self.skillGroupButton1.SetText(nameList.get(group, "Noname"))
				self.skillGroupButton2.SetText(localeInfo.SKILL_GROUP_HORSE)
				self.skillGroupButton1.Show()
				self.skillGroupButton2.Show()

			else:
				self.activeSkillGroupName.SetText(nameList.get(group, "Noname"))
				self.activeSkillGroupName.Show()
				self.skillGroupButton1.Hide()
				self.skillGroupButton2.Hide()

	def __SetSkillSlotData(self, race, group, empire=0):

		## SkillIndex
		playersettingmodule.RegisterSkill(race, group, empire)

		## Event
		self.__SetSkillSlotEvent()

		## Refresh
		self.RefreshSkill()

	def __SelectSkillGroup(self, index):
		for btn in self.skillGroupButton:
			btn.SetUp()
		self.skillGroupButton[index].Down()

		if self.__CanUseHorseSkill():
			if 0 == index:
				index = net.GetMainActorSkillGroup()-1
			elif 1 == index:
				index = self.PAGE_HORSE

		self.curSelectedSkillGroup = index
		self.__SetSkillSlotData(net.GetMainActorRace(), index+1, net.GetMainActorEmpire())

	def __CanUseSkillNow(self):
		if 0 == net.GetMainActorSkillGroup():
			return False

		return True

	def __CanUseHorseSkill(self):

		slotIndex = player.GetSkillSlotIndex(player.SKILL_INDEX_RIDING)

		if not slotIndex:
			return False

		grade = player.GetSkillGrade(slotIndex)
		level = player.GetSkillLevel(slotIndex)
		if level < 0:
			level *= -1
		if grade >= 1 and level >= 1:
			return True

		return False

	def __IsChangedHorseRidingSkillLevel(self):
		ret = False

		if -1 == self.canUseHorseSkill:
			self.canUseHorseSkill = self.__CanUseHorseSkill()

		if self.canUseHorseSkill != self.__CanUseHorseSkill():
			ret = True

		self.canUseHorseSkill = self.__CanUseHorseSkill()
		return ret

	if app.ENABLE_SKILLS_LEVEL_OVER_P:
		def __GetRealSkillSlot(self, skillGrade, skillSlot):
			_min = skill.SKILL_GRADE_COUNT - 1
			if app.ENABLE_SKILLS_LEVEL_OVER_P:
				_min -= 1
				if skillGrade == 2:
					skillGrade -= 1
			
			__calc = skillSlot + min(_min, skillGrade) * skill.SKILL_GRADE_STEP_COUNT
			return __calc
	else:
		def __GetRealSkillSlot(self, skillGrade, skillSlot):
			return skillSlot + min(skill.SKILL_GRADE_COUNT-1, skillGrade)*skill.SKILL_GRADE_STEP_COUNT

	def __GetETCSkillRealSlotIndex(self, skillSlot):
		if skillSlot > 100:
			return skillSlot
		return skillSlot % self.ACTIVE_PAGE_SLOT_COUNT

	def __RealSkillSlotToSourceSlot(self, realSkillSlot):
		if realSkillSlot > 100:
			return realSkillSlot
		if self.PAGE_HORSE == self.curSelectedSkillGroup:
			return realSkillSlot + self.ACTIVE_PAGE_SLOT_COUNT
		return realSkillSlot % skill.SKILL_GRADE_STEP_COUNT

	def __GetSkillGradeFromSlot(self, skillSlot):
		return int(skillSlot / skill.SKILL_GRADE_STEP_COUNT)

	def SelectSkillGroup(self, index):
		self.__SelectSkillGroup(index)

	def OnQuestScroll(self):
		questCount = quest.GetQuestCount()
		scrollLineCount = max(0, questCount - quest.QUEST_MAX_NUM)
		startIndex = int(scrollLineCount * self.questScrollBar.GetPos())

		if startIndex != self.questShowingStartIndex:
			self.questShowingStartIndex = startIndex
			self.RefreshQuest()
