local GlobalAddonName, BH = ...

local VBH = nil

local module = BH:New("Note",BH.L.message,nil,true)
local BHLib,L = BH.lib,BH.L

local GetTime, CombatLogGetCurrentEventInfo = GetTime, CombatLogGetCurrentEventInfo
local string_gsub, strsplit, tonumber, format = string.gsub, strsplit, tonumber, format



module.db.bhiconsList = {
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_2:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_3:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_4:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_5:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_6:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_7:0|t",
	"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_8:0|t",
}

module.db.bhiconsLocalizatedNames = {
	L.raidtargeticon1,L.raidtargeticon2,L.raidtargeticon3,L.raidtargeticon4,L.raidtargeticon5,L.raidtargeticon6,L.raidtargeticon7,L.raidtargeticon8,
}

local iconsLangs = {"eng","fr"}
for _,lang in pairs(iconsLangs) do
	module.db["icons"..lang.."Names"] = {}
	for i=1,8 do
		module.db["icons"..lang.."Names"][i] = L["raidtargeticon"..i.."_"..lang]
	end
end

local frameStrataList = {"BACKGROUND","LOW","MEDIUM","HIGH","DIALOG","FULLSCREEN","FULLSCREEN_DIALOG","TOOLTIP"}

module.db.bhmsgindex = -1
module.db.bhlasttext = ""

module.db.bhencounter_time_p = {}	--phases
module.db.bhencounter_time_c = {}	--custom
module.db.bhencounter_id = {}

local function GSUB_Icon(spellID) -- sert a afficher l'icon du spell
	spellID = tonumber(spellID)
	
	local spellTexture = select(3,GetSpellInfo(spellID))
	spellTexture = "|T"..(spellTexture or "Interface\\Icons\\INV_MISC_QUESTIONMARK")..":16|t"

	return spellTexture

end
local function GSUB_Icon2(spellID) -- sert a afficher l'icon du spell
	spellID = tonumber(spellID)
	
	local spellTexture = select(3,GetSpellInfo(spellID))
	spellTexture = "|T"..(spellTexture or "Interface\\Icons\\INV_MISC_QUESTIONMARK")..":12|t"

	return spellTexture
end


--[[
formats:
{time:75}
{time:1:15}
{time:2:30,p2}	--start on phase 2, works only with bigwigs
{time:0:30,SCC:17:2}	--start on combat log event. format "event:spellID:counter", events: SCC (SPELL_CAST_SUCCESS), SCS (SPELL_CAST_START), SAA (SPELL_AURA_APPLIED), SAR (SPELL_AURA_REMOVED)
{time:0:30,e,customevent}	--start on BH.F.Note_Timer(customevent) function or "/rt note starttimer customevent" 
]]
local function GSUB_Time(t,msg) --sert au timer dans la note
	local lineTime
	if t:find(":") then
		lineTime = tonumber(t:match("(%d+):") or "0",nil) * 60 + tonumber(t:match(":(%d+)") or "0",nil)
	else
		lineTime = tonumber(t:match("^(%d+)") or "0",nil)
	end

	local phase = t:match(",p(%d+)")

	if not module.db.bhencounter_time then
		return "|cffffed88"..(phase and "P"..phase.." " or "")..format("%d:%02d|r ",floor(lineTime/60),lineTime % 60)..msg.."\n"
	end

	local currTime = GetTime() - module.db.bhencounter_time

	local CLEU = t:match(",S")
	if CLEU then
		local _,lineMark = strsplit(",",t)
		t = module.db.bhencounter_counters_time[lineMark or ""]
		if t then
			currTime = GetTime() - t
		else
			return "|cffffed88"..format("%d:%02d|r ",floor(lineTime/60),lineTime % 60)..msg.."\n"
		end
	end

	local phaseText = ""
	if phase then
		t = module.db.bhencounter_time_p[tonumber(phase)]
		if not t then
			return "|cffffed88"..format("P%s %d:%02d|r ",phase,floor(lineTime/60),lineTime % 60)..msg.."\n"
		end
		currTime = GetTime() - t

		phaseText = "P"..phase.." "
	end

	if type(t)=='string' then
		local custom_event = t:match(",e,(.+)")
		if custom_event then
			t = module.db.bhencounter_time_c[custom_event]
			if not t then
				return "|cffffed88"..format("%d:%02d|r ",floor(lineTime/60),lineTime % 60)..msg.."\n"
			end
			currTime = GetTime() - t
		end
	end

	if currTime > lineTime then
		return "|cff555555"..msg:gsub("|c........",""):gsub("|r","").."|r\n"
	elseif lineTime - currTime <= 10 then
		t = lineTime - currTime
		return "|cff00ff00"..phaseText..format("%d:%02d ",floor(t/60),t % 60)..msg:gsub("|c........",""):gsub("|r",""):gsub(BH.SDB.charName,"|r|cffff0000>%1<|r|cff00ff00").."|r\n"
	else
		t = lineTime - currTime
		return "|cffffed88"..phaseText..format("%d:%02d|r ",floor(t/60),t % 60)..msg.."\n"
	end
end

local function txtWithIcons(t)
	t = t or ""

	if not t:find("{self}") then
		t = t..(t~="" and t~=" " and "\n" or "").."{self}"
	end
	t = string_gsub(t,"{self}",VBH.Note.SelfText or "")

	for i=1,8 do
		t = string_gsub(t,module.db.bhiconsLocalizatedNames[i],module.db.bhiconsList[i])
		t = string_gsub(t,"{rt"..i.."}",module.db.bhiconsList[i])
		for _,lang in pairs(iconsLangs) do
			t = string_gsub(t,module.db["icons"..lang.."Names"][i],module.db.bhiconsList[i])
		end
	end
	t = string_gsub(t,"||c","|c")
	t = string_gsub(t,"||r","|r")
	t = string_gsub(t,"{icon:([^}]+)}","|T%1:16|t")	
	t = string_gsub(t,"{spell:(%d+)}",GSUB_Icon)
	t = string_gsub(t.."\n","{time:([0-9:]+[^{}]*)}(.-)\n",GSUB_Time)
	t = string_gsub(t, "\n$", "")

	t = string_gsub(t,"%b{}","")
	return t
end

local IsUpdateNoteByEncounterFromMe = nil

function module.options:Load()
	self:CreateTilte()

	module.db.bhotherIconsAdditionalList = {
		31821,31884,"",62618,271466,64843,265202,"",98008,108280,"",115310,"",740,31884,"",0,
		97462,196718,0,
		20707,0,
	}
	--[[
	Script for autoicons:
	
	/run function F(eID)local f=select(4,EJ_GetEncounterInfoByIndex(eID))repeat local I=C_EncounterJournal.GetSectionInfo(f)local O=I and (I.headerType == 3)if O then f=I.siblingSectionID end until not O return f end
	/run function C(f) local I=C_EncounterJournal.GetSectionInfo(f) if I.firstChildSectionID then C(I.firstChildSectionID)end if I.spellID and I.spellID~=0 and P(I.spellID) then L[I.spellID]=true end if I.siblingSectionID then C(I.siblingSectionID) end end
	/run function P(s)local i=GetSpellTexture(s)if not U[i]then U[i]=1 return true end end for i=1,12 do L,U={},{} local f=F(i) C(f)local s="" for q,w in pairs(L)do s=s..q.."," end print(s..'0,')JJBox(s..'0,') end
	]]

	local BlackNoteNow = nil
	local NoteIsSelfNow = nil
	self.IsMainNoteNow = true
	
	--self.decorationLine = CreateFrame("Frame",nil,self)
	--self.decorationLine.texture = self.decorationLine:CreateTexture(nil, "BACKGROUND", nil, -5)
	--self.decorationLine:SetPoint("TOPLEFT",self,8,-25)
	--self.decorationLine:SetPoint("BOTTOMRIGHT",self,"TOPRIGHT",0,-45)
	--self.decorationLine.texture:SetAllPoints()
	--self.decorationLine.texture:SetColorTexture(1,1,1,1)
	--self.decorationLine.texture:SetGradientAlpha("VERTICAL",.24,.25,.30,1,.27,.28,.33,1)

	self.tab = BHLib:Tabs(self,"BHTabButtonTemplate",L.message,L.minimapmenuset,HELP_LABEL):Point(10,-45):Size(797,570):SetTo(1)
	self.tab:SetBackdropBorderColor(0,0,0,0)
	self.tab:SetBackdropColor(0,0,0,0)
	
	self.tab.tabs[1]:SetPoint("TOPLEFT",0,20)
	
	self.chkEnable = BHLib:Check(self,L.senable,VBH.Note.enabled,0):Point(560+130,-26):Tooltip("/rt note|n/rt n"):Size(25,25):OnClick(function(self) 
		if self:GetChecked() then
			module:Enable()
		else
			module:Disable()
		end
	end)  
	
	self.chkFix = BHLib:Check(self,L.messagebutfix,VBH.Note.Fix,0):Point(430+130,-26):Tooltip(L.messagebutfixtooltip):Size(25,25):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.Fix = true
			module.frame:SetMovable(false)
			module.frame:EnableMouse(false)
			module.frame.buttonResize:Hide()
			BH.lib.AddShadowComment(module.frame,1)
		else
			VBH.Note.Fix = nil
			module.frame:SetMovable(true)
			module.frame:EnableMouse(true)
			module.frame.buttonResize:Show()
			BH.lib.AddShadowComment(module.frame,nil,L.message)
		end
	end) 

	self.NotesList = BHLib:ScrollList(self.tab.tabs[1]):Size(175+37,435):Point(5,-130)
	self.NotesList.selected = 1

	local function SwapBlackNotes(noteFrom,noteTo)
		if noteTo < 1 or noteFrom < 1 or noteTo > #VBH.Note.Black or noteFrom > #VBH.Note.Black or not VBH.Note.Black[noteTo] or not VBH.Note.Black[noteFrom] then
			return
		end
		local text = VBH.Note.Black[noteTo]
		local title = VBH.Note.BlackNames[noteTo]
		local boss = VBH.Note.AutoLoad[noteTo]
		local lastUpdateName = VBH.Note.BlackLastUpdateName[noteTo]
		local lastUpdateTime = VBH.Note.BlackLastUpdateTime[noteTo]

		VBH.Note.Black[noteTo] = VBH.Note.Black[noteFrom]
		VBH.Note.BlackNames[noteTo] = VBH.Note.BlackNames[noteFrom]
		VBH.Note.AutoLoad[noteTo] = VBH.Note.AutoLoad[noteFrom]
		VBH.Note.BlackLastUpdateName[noteTo] = VBH.Note.BlackLastUpdateName[noteFrom]
		VBH.Note.BlackLastUpdateTime[noteTo] = VBH.Note.BlackLastUpdateTime[noteFrom]

		VBH.Note.Black[noteFrom] = text
		VBH.Note.BlackNames[noteFrom] = title
		VBH.Note.AutoLoad[noteFrom] = boss
		VBH.Note.BlackLastUpdateName[noteFrom] = lastUpdateName
		VBH.Note.BlackLastUpdateTime[noteFrom] = lastUpdateTime

		module.options:NotesListUpdateNames()
		module.options.NotesList.selected = noteTo + 2
		module.options.NotesList:Update()
	end
	
	local function NotesListUpdateNames()
		self.NotesList.L = {}	
		self.NotesList.L[1] = "|cff55ee55"..L.messageTab1
		self.NotesList.L[2] = L.NoteSelf
		for i=1,#VBH.Note.Black do
			self.NotesList.L[i+2] = VBH.Note.BlackNames[i] or i
		end
		self.NotesList.L[#self.NotesList.L + 1] = L.NoteAdd
		self.NotesList:Update()
	end
	NotesListUpdateNames()
	self.NotesListUpdateNames = NotesListUpdateNames
	
	local function UpdatePageAfterGettingNote()
		if NoteIsSelfNow then
			self.NotesList:SetListValue(2)
		elseif BlackNoteNow then
			self.NotesList:SetListValue(BlackNoteNow + 2)
		else
			self.NotesList:SetListValue(1)
		end
	end
	self.UpdatePageAfterGettingNote = UpdatePageAfterGettingNote
	
	module.options.LastIndex = 1
	function self.NotesList:SetListValue(index)
		module.options.LastIndex = index

		BH.lib.ShowOrHide(module.options.buttonsend,index == 1)
		BH.lib.ShowOrHide(module.options.buttoncopy,index > 2)
		
		BlackNoteNow = nil
		NoteIsSelfNow = nil
		module.options.IsMainNoteNow = nil
		
		if index == 1 then
			module.options.DraftName:Enable()
			module.options.RemoveDraft:Disable()
		
		elseif index > 2 then
			module.options.DraftName:Enable()
			module.options.RemoveDraft:Enable()
			
		else
			module.options.DraftName:Disable()
			module.options.RemoveDraft:Disable()
		
		end
		
		if index == 1 then
			module.options.NoteEditBox.EditBox:SetText(VBH.Note.Text1 or "")
			--module.options.DraftName:SetText( L.messageTab1 )
			
			module.options.IsMainNoteNow = true
			
			module.options.DraftName:SetText( VBH.Note.DefName or "" )
			
			
		elseif index == 2 then
			module.options.NoteEditBox.EditBox:SetText(VBH.Note.SelfText or "")
			module.options.DraftName:SetText( L.NoteSelf )
			
			
			NoteIsSelfNow = true
		elseif index == #self.L then
			VBH.Note.Black[#VBH.Note.Black + 1] = ""
			tinsert(self.L,#self.L - 1,#VBH.Note.Black)
			module.options.NoteEditBox.EditBox:SetText("")
			self:Update()
			
			BlackNoteNow = #VBH.Note.Black
			module.options.DraftName:SetText( BlackNoteNow )
			
			NotesListUpdateNames()
			
		else
			index = index - 2
			if IsShiftKeyDown() then
				VBH.Note.Black[index] = VBH.Note.Text1
			end
			module.options.NoteEditBox.EditBox:SetText(VBH.Note.Black[index] or "")
			
			BlackNoteNow = index
			module.options.DraftName:SetText( VBH.Note.BlackNames[index] or index )
		end
	end

	self.NotesList:SetScript("OnShow",function(self)
		NotesListUpdateNames()
	end)
	
	function self.NotesList:HoverListValue(isHover,index)
		if not isHover then
			GameTooltip_Hide()
		else
			GameTooltip:SetOwner(self,"ANCHOR_CURSOR")
			GameTooltip:AddLine(self.L[index])
			if index == 2 then
				GameTooltip:AddLine(L.NoteSelfTooltip)
			elseif index ~= #self.L and index > 2 then
				local i = index - 2
				if VBH.Note.BlackLastUpdateName[i] then
					GameTooltip:AddLine(L.NoteLastUpdate..": "..VBH.Note.BlackLastUpdateName[i].." ("..date("%d.%m.%Y %H:%M",VBH.Note.BlackLastUpdateTime[i] or 0)..")")
				end
				--GameTooltip:AddLine(L.NoteTabCopyTooltip)
			end
			GameTooltip:Show()
		end
	end

	self.DuplicateDraft = BHLib:Button(self.tab.tabs[1],L.NoteDuplicate):Size(120,20):Point("RIGHT",0,0):Point("TOP",self.NotesList,0,1):OnClick(function (self)
		local pos = #VBH.Note.Black + 1

		local text = module.options.LastIndex == 1 and (VBH.Note.Text1 or "") or
				module.options.LastIndex == 2 and (VBH.Note.SelfText or "") or
				(VBH.Note.Black[module.options.LastIndex - 2] or "")
		local title = (module.options.LastIndex > 2 and VBH.Note.BlackNames[module.options.LastIndex - 2]) or 
				(module.options.LastIndex == 1 and VBH.Note.DefName)
		if not title then title = nil end

		local boss = module.options.LastIndex == 1 and VBH.Note.AutoLoad[0] or
				module.options.LastIndex > 2 and VBH.Note.AutoLoad[module.options.LastIndex - 2]
		if not boss then boss = nil end

		local lastUpdateName = module.options.LastIndex > 2 and VBH.Note.BlackLastUpdateName[module.options.LastIndex - 2]
		if not lastUpdateName then lastUpdateName = nil end

		local lastUpdateTime = module.options.LastIndex > 2 and VBH.Note.BlackLastUpdateTime[module.options.LastIndex - 2]
		if not lastUpdateTime then lastUpdateTime = nil end

		VBH.Note.Black[pos] = text
		VBH.Note.BlackNames[pos] = title
		VBH.Note.AutoLoad[pos] = boss
		VBH.Note.BlackLastUpdateName[pos] = lastUpdateName
		VBH.Note.BlackLastUpdateTime[pos] = lastUpdateTime

		NotesListUpdateNames()
		module.options.NotesList:SetListValue(pos+2)
		module.options.NotesList.selected = pos+2
		module.options.NotesList:Update()
	end)
	
	self.RemoveDraft = BHLib:Button(self.tab.tabs[1],L.NoteRemove):Size(120,20):Point("RIGHT",self.DuplicateDraft,"LEFT",-5,0):Point("TOP",self.NotesList,0,1):Disable():OnClick(function (self)
		if not BlackNoteNow then
			return
		end
		local size = #VBH.Note.Black
		for i=BlackNoteNow,size do
			if i < size then
				VBH.Note.Black[i] = VBH.Note.Black[i + 1]
				VBH.Note.BlackNames[i] = VBH.Note.BlackNames[i + 1]
				VBH.Note.AutoLoad[i] = VBH.Note.AutoLoad[i + 1]
				VBH.Note.BlackLastUpdateName[i] = VBH.Note.BlackLastUpdateName[i + 1]
				VBH.Note.BlackLastUpdateTime[i] = VBH.Note.BlackLastUpdateTime[i + 1]
			else
				VBH.Note.Black[i] = nil
				VBH.Note.BlackNames[i] = nil
				VBH.Note.AutoLoad[i] = nil
				VBH.Note.BlackLastUpdateName[i] = nil
				VBH.Note.BlackLastUpdateTime[i] = nil
			end
		end
		NotesListUpdateNames()
		if BlackNoteNow == (#module.options.NotesList.L - 2) then
			BlackNoteNow = BlackNoteNow - 1
		end
		module.options.NotesList:SetListValue(2+BlackNoteNow)
		module.options.NotesList.selected = 2+BlackNoteNow
		module.options.NotesList:Update()
	end)
	
	self.DraftName = BHLib:Edit(self.tab.tabs[1]):Size(0,18):Tooltip(L.NoteDraftName):Text(VBH.Note.DefName or L.messageTab1):Point("TOPLEFT",self.NotesList,"TOPRIGHT",8,0):Point("RIGHT",self.RemoveDraft,"LEFT",-5,0):OnChange(function(self,isUser)
		if not isUser then return end
		if BlackNoteNow then
			VBH.Note.BlackNames[ BlackNoteNow ] = self:GetText()
			NotesListUpdateNames()
		elseif not BlackNoteNow and not NoteIsSelfNow then
			VBH.Note.DefName = self:GetText()
		end
	end)

	local IsFormattingOn = VBH.Note.OptionsFormatting
	self.optFormatting = BHLib:Check(self.tab.tabs[1],FORMATTING,VBH.Note.OptionsFormatting,0):Point("TOPLEFT",self.NotesList,"TOPRIGHT",9,-25):Size(20,20):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.OptionsFormatting = true
		else
			VBH.Note.OptionsFormatting = nil
		end
		IsFormattingOn = VBH.Note.OptionsFormatting
		module.options.NotesList:SetListValue(module.options.LastIndex or 1)
	end)  	
	
	self.NoteEditBox = BHLib:MultiEdit(self.tab.tabs[1]):Point("TOPLEFT",self.NotesList,"TOPRIGHT",9,-75):Size(469+100,294+91-25)


	self.NoteEditBox.EditBox._SetText = self.NoteEditBox.EditBox.SetText
	function self.NoteEditBox.EditBox:SetText(text)
		if IsFormattingOn then
			text = text:gsub("||([cr])","|%1")
			text = text:gsub("{spell:(%d+)}",GSUB_Icon2)
			
		end
		return self:_SetText(text)
	end
	
	self.textClear = BHLib:Text(self.NoteEditBox,"["..L.messagebutclear.."]"):Point("RIGHT",self.NoteEditBox,"BOTTOMRIGHT",-22,-6):Color()
	self.textClear:SetShadowColor(1,1,1,0)
	self.textClear:SetShadowOffset(1,-1)
	self.buttonClear = CreateFrame("Button",nil,self.NoteEditBox)
	self.buttonClear:SetAllPoints(self.textClear)
	self.buttonClear:SetScript("OnClick",function()
		module.frame:Clear() 
		module.options.NoteEditBox.EditBox:SetText("")
	end)
	self.buttonClear:SetScript("OnEnter",function()
		self.textClear:SetShadowColor(1,1,1,1)
	end)
	self.buttonClear:SetScript("OnLeave",function()
		self.textClear:SetShadowColor(1,1,1,0)
	end)
	
		
	function self.NoteEditBox.EditBox:OnTextChanged(isUser)
		if not isUser and (not module.options.InsertFix or GetTime() - module.options.InsertFix > 0.1) then
			return
		end
		local text = self:GetText()
		if IsFormattingOn then
			text = text:gsub("|([cr])","||%1")
			text = text:gsub("{spell:(%d+)}",GSUB_Icon2)
		end
		if NoteIsSelfNow then
			VBH.Note.SelfText = text
			module.frame:UpdateText()
		elseif BlackNoteNow then
			VBH.Note.Black[ BlackNoteNow ] = text

			VBH.Note.BlackLastUpdateName[BlackNoteNow] = BH.SDB.charKey
			VBH.Note.BlackLastUpdateTime[BlackNoteNow] = time()
		else
			VBH.Note.Text1 = text
			if module.frame.text:GetText() ~= txtWithIcons(VBH.Note.Text1) then
				module.options.buttonsend:Anim(true)
			else
				module.options.buttonsend:Anim(false)
			end
		end
	end
	local last_highlight_start,last_highlight_end,last_cursor_pos = 0,0,0
	local IsFormattingOn_Saved
	self.NoteEditBox.EditBox:SetScript("OnKeyDown",function(self,key)
		if IsFormattingOn and key == "LCTRL" then
			module.options.InsertFix = nil
			IsFormattingOn_Saved = true
			IsFormattingOn = nil
			local h_start,h_end = module.options.NoteEditBox:GetTextHighlight()
			local h_cursor = self:GetCursorPosition()
			local text = module.options.NoteEditBox.EditBox:GetText()

			last_highlight_start,last_highlight_end,last_cursor_pos = h_start,h_end,h_cursor
			
			local c_start,c_end,c_cursor = 0,0,0
			text:sub(1,h_start):gsub("|([cr])",function() c_start = c_start + 1 end)
			text:sub(1,h_end):gsub("|([cr])",function() c_end = c_end + 1 end)
			text:sub(1,h_cursor):gsub("|([cr])",function() c_cursor = c_cursor + 1 end)

			text = text:gsub("|([cr])","||%1")
			text = text:gsub("{spell:(%d+)}",GSUB_Icon2)
			module.options.NoteEditBox.EditBox:_SetText(text)

			module.options.NoteEditBox.EditBox:HighlightText( h_start+c_start, h_end+c_end )
			module.options.NoteEditBox.EditBox:SetCursorPosition( h_cursor+c_cursor )
		end
	end)
	self.NoteEditBox.EditBox:SetScript("OnKeyUp",function(self,key)
		if IsFormattingOn_Saved and key == "LCTRL" then
			local text = module.options.NoteEditBox.EditBox:GetText()
			local h_start,h_end = module.options.NoteEditBox:GetTextHighlight()
			local h_cursor = self:GetCursorPosition()
			local c_start,c_end,c_cursor = 0,0,0
			text:sub(1,h_start):gsub("||([cr])",function() c_start = c_start + 1 end)
			text:sub(1,h_end):gsub("||([cr])",function() c_end = c_end + 1 end)
			text:sub(1,h_cursor):gsub("||([cr])",function() c_cursor = c_cursor + 1 end)
			
			IsFormattingOn = true
			IsFormattingOn_Saved = nil
			module.options.InsertFix = nil
			module.options.NotesList:SetListValue(module.options.LastIndex or 1)
			module.options.NoteEditBox.EditBox:HighlightText( h_start-c_start,h_end-c_end )
			module.options.NoteEditBox.EditBox:SetCursorPosition( h_cursor-c_cursor )
		end
	end)
	
	self.buttonsend = BHLib:Button(self.tab.tabs[1],L.messagebutsend):Size(469+102,20):Point("TOPLEFT",self.NotesList,"TOPRIGHT",9,-50):Tooltip(L.messagebutsendtooltip):OnClick(function (self)
		module.frame:Save() 
		
		if IsShiftKeyDown() then
			local text = VBH.Note.Text1 or ""
			text = text:gsub("||c........","")
			text = text:gsub("||r","")
			text = text:gsub("||T.-:0||t ","")
			text = text:gsub("%b{}","")
			
			local lines = {strsplit("\n", text)}
			for i=1,#lines do
				if lines[i] ~= "" then
					SendChatMessage(lines[i],(IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT") or (IsInRaid() and "RAID") or "PARTY")
				end
			end
		end
		
		module.options.buttonsend:Anim(false)
	end) 
	
	function self.buttonsend:Anim(on)
		if on then
			self.t = self.t or 0
			self:SetScript("OnUpdate",function(self,elapsed)
				self.t = (self.t + elapsed) % 4
				
				local c = 0.05 * (self.t > 2 and (4-self.t) or self.t)
				
				self.Texture:SetGradientAlpha("VERTICAL",0.0+c,0.06+c,0.0+c,1, 0.05+c,0.21+c,0.05+c,1)
			end)
		else
			self:SetScript("OnUpdate",nil)
			self.Texture:SetGradientAlpha("VERTICAL",0.05,0.06,0.09,1, 0.20,0.21,0.25,1)
		end
	end
	
	self.buttoncopy = BHLib:Button(self.tab.tabs[1],L.messageButCopy):Size(469+102,20):Point("TOPLEFT",self.NotesList,"TOPRIGHT",9,-50):OnClick(function (self)
		if not BlackNoteNow then
			return
		end
		module.frame:Save(BlackNoteNow) 
		
		module.options.NotesList:SetListValue(1)
		
		module.options.NotesList.selected = 1
		module.options.NotesList:Update()
	end) 
	self.buttoncopy:Hide()
	
	local function AddTextToEditBox(self,text,mypos,noremove)
		local addedText = nil
		if not self then
			addedText = text
		else
			addedText = self.iconText
			if IsShiftKeyDown() then
				addedText = self.iconTextShift
			end
		end
		if not noremove then
			module.options.NoteEditBox.EditBox:Insert("")
		end
		local txt = module.options.NoteEditBox.EditBox:GetText()
		local pos = module.options.NoteEditBox.EditBox:GetCursorPosition()
		if not self and type(mypos)=='number' then
			pos = mypos
		end
		txt = string.sub (txt, 1 , pos) .. addedText .. string.sub (txt, pos+1)
		module.options.InsertFix = GetTime()
		module.options.NoteEditBox.EditBox:SetText(txt)
		local adjust = 0
		if IsFormattingOn then
			addedText:gsub("||",function() adjust = adjust + 1 end)
		end
		module.options.NoteEditBox.EditBox:SetCursorPosition(pos+addedText:len()-adjust)
	end

	self.buttonicons = {}
	for i=1,8 do
		self.buttonicons[i] = CreateFrame("Button", nil,self.tab.tabs[1])
		self.buttonicons[i]:SetSize(18,18)
		self.buttonicons[i]:SetPoint("TOPLEFT", 5+(i-1)*20,-30)
		self.buttonicons[i].back = self.buttonicons[i]:CreateTexture(nil, "BACKGROUND")
		self.buttonicons[i].back:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_"..i)
		self.buttonicons[i].back:SetAllPoints()
		self.buttonicons[i]:RegisterForClicks("LeftButtonDown")
		self.buttonicons[i].iconText = module.db.bhiconsLocalizatedNames[i]
		self.buttonicons[i]:SetScript("OnClick", AddTextToEditBox)
	end
	
	self.OtherIconsButton = BHLib:Button(self.tab.tabs[1],L.NoteOtherIcons):Size(120,20):Point("TOPLEFT",165,-30):OnClick(function()
		module.options.OtherIconsFrame:ShowClick("TOPRIGHT")
	end)
	
	self.OtherIconsFrame = BHLib:Popup(L.NoteOtherIcons):Size(350,150)
	self.OtherIconsFrame.ScrollFrame = BHLib:ScrollFrame(self.OtherIconsFrame,0,130):Size(self.OtherIconsFrame:GetWidth()-10,self.OtherIconsFrame:GetHeight()-25):Point("TOP",0,-20):Height(500)
	
	local function CreateOtherIcon(pointX,pointY,texture,iconText)
		local self = CreateFrame("Button", nil,self.OtherIconsFrame.ScrollFrame.C)
		self:SetSize(18,18)
		self:SetPoint("TOPLEFT",pointX,pointY)
		self.texture = self:CreateTexture(nil, "BACKGROUND")
		self.texture:SetTexture(texture)
		self.texture:SetAllPoints()
		self:RegisterForClicks("LeftButtonDown")
		self.iconText = iconText
		self:SetScript("OnClick", AddTextToEditBox)
		return self
	end
	
	do
		local GetSpellInfo = GetSpellInfo
		local line = 2
		local inLine = 0
		for i=1,#module.db.bhotherIconsAdditionalList do
			local spellID = module.db.bhotherIconsAdditionalList[i]
			if spellID == 0 then
				line = line + 1
				inLine = 0
			elseif type(spellID) == 'string' then
				CreateOtherIcon(5+inLine*20,-2-(line-1)*20,spellID,"||T"..spellID..":0||t")
				inLine = inLine + 1
				if inLine > 12 and (not module.db.bhotherIconsAdditionalList[i+1] or module.db.bhotherIconsAdditionalList[i+1]~=0) then
					line = line + 1
					inLine = 0
				end
			else
				local _,_,spellTexture = GetSpellInfo( spellID )
				
				CreateOtherIcon(5+inLine*20,-2-(line-1)*20,spellTexture,"{spell:"..spellID.."}")
				inLine = inLine + 1
				if inLine > 12 and (not module.db.bhotherIconsAdditionalList[i+1] or module.db.bhotherIconsAdditionalList[i+1]~=0) then
					line = line + 1
					inLine = 0
				end
			end
		end
		self.OtherIconsFrame.ScrollFrame:SetNewHeight( max(self.OtherIconsFrame:GetHeight()-40 , line * 20 + 4) )
	end
	
	self:SetScript("OnHide",function (self)
		self.OtherIconsFrame:Hide()
	end)
	
	self.dropDownColor = BHLib:DropDown(self.tab.tabs[1],170,10):Point(558,-30):Size(100):SetText(L.NoteColor)
	self.dropDownColor.list = {
		{L.NoteColorRed,"|cffff0000"},
		{L.NoteColorGreen,"|cff00ff00"},
		{L.NoteColorBlue,"|cff0000ff"},
		{L.NoteColorYellow,"|cffffff00"},
		{L.NoteColorPurple,"|cffff00ff"},
		{L.NoteColorAzure,"|cff00ffff"},
		{L.NoteColorBlack,"|cff000000"},
		{L.NoteColorGrey,"|cff808080"},
		{L.NoteColorRedSoft,"|cffee5555"},
		{L.NoteColorGreenSoft,"|cff55ee55"},
		{L.NoteColorBlueSoft,"|cff5555ee"},
	}
	local classNames = BH.GDB.ClassList
	for i,class in ipairs(classNames) do
		local colorTable = RAID_CLASS_COLORS[class]
		if colorTable then
			self.dropDownColor.list[#self.dropDownColor.list + 1] = {L.classLocalizate[class],"|c"..colorTable.colorStr}
		end
	end
	self.dropDownColor:SetScript("OnEnter",function (self)
		BHLib.Tooltip.Show(self,"ANCHOR_LEFT",L.NoteColor,{L.NoteColorTooltip1,1,1,1,true},{L.NoteColorTooltip2,1,1,1,true})
	end)
	self.dropDownColor:SetScript("OnLeave",function ()
		BHLib.Tooltip:Hide()
	end)
	function self.dropDownColor:SetValue(colorCode)
		BHLib:DropDownClose()

		local selectedStart,selectedEnd = module.options.NoteEditBox.EditBox:GetTextHighlight()
		colorCode = string.gsub(colorCode,"|","||")
		if selectedStart == selectedEnd then
			AddTextToEditBox(nil,colorCode.."||r",nil,true)
		else
			AddTextToEditBox(nil,"||r",selectedEnd,true)
			AddTextToEditBox(nil,colorCode,selectedStart,true)
		end
	end
	for i=1,#self.dropDownColor.list do
		local colorData = self.dropDownColor.list[i]
		self.dropDownColor.List[i] = {
			text = colorData[2]..colorData[1],
			func = self.dropDownColor.SetValue,
			justifyH = "CENTER",
			arg1 = colorData[2],
		}
	end
	self.dropDownColor.Lines = #self.dropDownColor.List

	local function RaidNamesOnEnter(self)
		self.html:SetShadowColor(0.2, 0.2, 0.2, 1)
	end
	local function RaidNamesOnLeave(self)
		self.html:SetShadowColor(0, 0, 0, 1)
	end
	self.raidnames = {}
	
	-- ajout icon htt ...
	
	for i=1,40 do
		self.raidnames[i] = CreateFrame("Button", nil,self.tab.tabs[1])
		self.raidnames[i]:SetSize(93,14)
		self.raidnames[i]:SetPoint("TOPLEFT", 5+math.floor((i-1)/5)*95,-55-14*((i-1)%5))

		self.raidnames[i].html = BHLib:Text(self.raidnames[i],"",11):Color()
		self.raidnames[i].html:SetAllPoints()
		self.raidnames[i].txt = ""
		self.raidnames[i]:RegisterForClicks("LeftButtonDown")
		self.raidnames[i].iconText = ""
		self.raidnames[i]:SetScript("OnClick", AddTextToEditBox)

		self.raidnames[i]:SetScript("OnEnter", RaidNamesOnEnter)
		self.raidnames[i]:SetScript("OnLeave", RaidNamesOnLeave)

	end
	
	self.lastUpdate = BHLib:Text(self.tab.tabs[1],"",11):Size(600,20):Point("TOPLEFT",self.NotesList,"BOTTOMLEFT",3,-6):Top():Color()
	if VBH.Note.LastUpdateName and VBH.Note.LastUpdateTime then
		self.lastUpdate:SetText( L.NoteLastUpdate..": "..VBH.Note.LastUpdateName.." ("..date("%H:%M:%S %d.%m.%Y",VBH.Note.LastUpdateTime)..")" )
	end


	self.chkOnlyPromoted = BHLib:Check(self.tab.tabs[2],L.NoteOnlyPromoted,VBH.Note.OnlyPromoted,0):Point(10,-15):Tooltip(L.NoteOnlyPromotedTooltip):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.OnlyPromoted = true
		else
			VBH.Note.OnlyPromoted = nil
		end
	end)  
	
	
	self.chkOnlyInRaid = BHLib:Check(self.tab.tabs[2],L.MarksBarDisableInRaid,VBH.Note.HideOutsideRaid,0):Point(10,-40):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.HideOutsideRaid = true
		else
			VBH.Note.HideOutsideRaid = nil
		end
		module:Visibility()
	end) 
	
	self.chkOnlyInRaidKInstance = BHLib:Check(self.tab.tabs[2],L.NoteShowOnlyInRaid,VBH.Note.ShowOnlyInRaid,0):Point(10,-65):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.ShowOnlyInRaid = true
			module:RegisterEvents('ZONE_CHANGED_NEW_AREA')
		else
			VBH.Note.ShowOnlyInRaid = nil
			module:UnregisterEvents('ZONE_CHANGED_NEW_AREA')
		end
		module:Visibility()
	end) 
	
	self.chkOnlySelf = BHLib:Check(self.tab.tabs[2],L.NoteShowOnlyPersonal,VBH.Note.ShowOnlyPersonal,0):Point(10,-90):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.ShowOnlyPersonal = true
		else
			VBH.Note.ShowOnlyPersonal = nil
		end
		module.frame:UpdateText()
	end) 
	
	self.chkHideInCombat = BHLib:Check(self.tab.tabs[2],L.NoteHideInCombat,VBH.Note.HideInCombat,0):Point(10,-115):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.HideInCombat = true
			module:RegisterEvents('PLAYER_REGEN_DISABLED','PLAYER_REGEN_ENABLED')
		else
			VBH.Note.HideInCombat = nil
			module:UnregisterEvents('PLAYER_REGEN_DISABLED','PLAYER_REGEN_ENABLED')
		end
		module:Visibility()
	end) 
	
	self.chkSaveAllNew = BHLib:Check(self.tab.tabs[2],L.NoteSaveAllNew,VBH.Note.SaveAllNew,0):Point(10,-140):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.SaveAllNew = true
		else
			VBH.Note.SaveAllNew = nil
		end
	end) 
	
	self.chkSaveAllNew = BHLib:Check(self.tab.tabs[2],L.NoteEnableWhenReceive,VBH.Note.EnableWhenReceive,0):Point(10,-165):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.EnableWhenReceive = true
		else
			VBH.Note.EnableWhenReceive = nil
		end
	end) 
	
	self.sliderFontSize = BHLib:Slider(self.tab.tabs[2],L.NoteFontSize,false,0):Size(300,20):Point(11,-200):Range(6,72):SetTo(VBH.Note.FontSize or 12):OnChange(function(self,event) 
		event = event - event%1
		VBH.Note.FontSize = event
		module.frame:UpdateFont()
		self.tooltipText = event
		self:tooltipReload(self)
	end)
	
	local function DropDownFont_Click(_,arg)
		VBH.Note.FontName = arg
		local FontNameForDropDown = arg:match("\\([^\\]*)$")
		module.options.dropDownFont:SetText(FontNameForDropDown or arg)
		BHLib:DropDownClose()
		module.frame:UpdateFont()
	end

	self.dropDownFont = BHLib:DropDown(self.tab.tabs[2],350,10):Point(10,-230):Size(300)
	for i=1,#BH.F.fontList do
		self.dropDownFont.List[i] = {}
		local info = self.dropDownFont.List[i]
		info.text = BH.F.fontList[i]
		info.arg1 = BH.F.fontList[i]
		info.arg2 = i
		info.func = DropDownFont_Click
		info.font = BH.F.fontList[i]
		info.justifyH = "CENTER" 
	end
	if LibStub then
		local loaded,media = pcall(LibStub,"LibSharedMedia-3.0")
		if loaded and media then
			local fontList = media:HashTable("font")
			if fontList then
				local count = #self.dropDownFont.List
				for key,font in pairs(fontList) do
					count = count + 1
					self.dropDownFont.List[count] = {}
					local info = self.dropDownFont.List[count]
					
					info.text = font
					info.arg1 = font
					info.arg2 = count
					info.func = DropDownFont_Click
					info.font = font
					info.justifyH = "CENTER" 
				end
			end
		end
	end
	do
		local arg = VBH.Note.FontName or BH.F.defFont
		local FontNameForDropDown = arg:match("\\([^\\]*)$")
		self.dropDownFont:SetText(FontNameForDropDown or arg)
	end
	
	self.chkOutline = BHLib:Check(self.tab.tabs[2],L.messageOutline,VBH.Note.Outline,0):Point("LEFT",self.dropDownFont,"RIGHT",10,0):OnClick(function(self) 
		if self:GetChecked() then
			VBH.Note.Outline = true
		else
			VBH.Note.Outline = nil
		end
		module.frame:UpdateFont()
	end) 
	
	self.slideralpha = BHLib:Slider(self.tab.tabs[2],L.messagebutalpha,false,0):Size(300,20):Point(11,-275):Range(0,100):SetTo(VBH.Note.Alpha or 100):OnChange(function(self,event) 
		event = event - event%1
		VBH.Note.Alpha = event
		module.frame:SetAlpha(event/100)
		self.tooltipText = event
		self:tooltipReload(self)
	end)
	
	self.sliderscale = BHLib:Slider(self.tab.tabs[2],L.messagebutscale,false,0):Size(300,20):Point(11,-345):Range(5,200):SetTo(VBH.Note.Scale or 100):OnChange(function(self,event) 
		event = event - event%1
		VBH.Note.Scale = event
		BH.F.SetScaleFix(module.frame,event/100)
		self.tooltipText = event
		self:tooltipReload(self)
	end)

	self.slideralphaback = BHLib:Slider(self.tab.tabs[2],L.messageBackAlpha):Size(300):Point(11,-310):Range(0,100):SetTo(VBH.Note.ScaleBack or 100):OnChange(function(self,event) 
		event = event - event%1
		VBH.Note.ScaleBack = event
		module.frame.background:SetColorTexture(0, 0, 0, event/100)
		self.tooltipText = event
		self:tooltipReload(self)
	end)
	
	self.moreOptionsDropDown = BHLib:DropDown(self.tab.tabs[2],275,#frameStrataList+1):Point(10,-380):Size(300):SetText(L.NoteFrameStrata)
	
	local function moreOptionsDropDown_SetVaule(_,arg)
		VBH.Note.Strata = arg
		BHLib:DropDownClose()
		for i=1,#self.moreOptionsDropDown.List-1 do
			self.moreOptionsDropDown.List[i].checkState = VBH.Note.Strata == self.moreOptionsDropDown.List[i].arg1
		end
		module.frame:SetFrameStrata(arg)
	end
	
	for i=1,#frameStrataList do
		self.moreOptionsDropDown.List[i] = {
			text = frameStrataList[i],
			checkState = VBH.Note.Strata == frameStrataList[i],
			radio = true,
			arg1 = frameStrataList[i],
			func = moreOptionsDropDown_SetVaule,
		}
	end
	tinsert(self.moreOptionsDropDown.List,{text = L.minimapmenuclose, func = function()
		BHLib:DropDownClose()
	end})
	
	self.ButtonToCenter = BHLib:Button(self.tab.tabs[2],L.MarksBarResetPos):Size(300,20):Point(10,-410):Tooltip(L.MarksBarResetPosTooltip):OnClick(function()
		VBH.Note.Left = nil
		VBH.Note.Top = nil

		module.frame:ClearAllPoints()
		module.frame:SetPoint("CENTER",UIParent, "CENTER", 0, 0)
	end) 
	
	if VBH.Note.Text1 then 
		self.NoteEditBox.EditBox:SetText(VBH.Note.Text1) 
	end

	self.textHelp = BHLib:Text(self.tab.tabs[3],
		"|cffffff00||cffRRGGBB|r...|cffffff00||r|r - "..L.NoteHelp1..		
		"|n|cffffff00{spell:|r|cff00ff0017|r|cffffff00}|r - "..L.NoteHelp3..
		"|n|cffffff00{icon:|r|cff00ff00Interface/Icons/inv_hammer_unique_sulfuras|r|cffffff00}|r - "..L.NoteHelp6..
		"|n|cffffff00{time:|r|cff00ff002:45|r|cffffff00}|r - "..L.NoteHelp7
	):Point("TOPLEFT",5,-20):Point("TOPRIGHT",-5,-20):Color()

	module:RegisterEvents("GROUP_ROSTER_UPDATE")
	module.main:GROUP_ROSTER_UPDATE()


	local function ResizeOptionFrameShow() BH.Options.Frame:SetWidth( 920 ) end
	local function ResizeOptionFrameHide() BH.Options.Frame:SetWidth( BH.Options.Frame.Width ) end
	self.onShowFrame = CreateFrame('Frame',nil,self)
	self.onShowFrame:SetPoint("TOPLEFT",0,0)
	self.onShowFrame:SetSize(1,1)
	self.onShowFrame:SetScript("OnShow",ResizeOptionFrameShow)
	self.onShowFrame:SetScript("OnHide",ResizeOptionFrameHide)
	ResizeOptionFrameShow()

	self:SetWidth(797)
end


module.frame = CreateFrame("Frame",nil,UIParent)
module.frame:SetSize(200,100)
module.frame:SetPoint("CENTER",UIParent, "CENTER", 0, 0)
module.frame:EnableMouse(true)
module.frame:SetMovable(true)
module.frame:RegisterForDrag("LeftButton")
module.frame:SetScript("OnDragStart", function(self)
	if self:IsMovable() then
		self:StartMoving()
	end
end)
module.frame:SetScript("OnDragStop", function(self)
	self:StopMovingOrSizing()
	VBH.Note.Left = self:GetLeft()
	VBH.Note.Top = self:GetTop()
end)
module.frame:SetFrameStrata("HIGH")
module.frame:SetResizable(true)
module.frame:SetMinResize(30, 30)
module.frame:SetScript("OnSizeChanged", function (self, width, height)
	local width_, height_ = self:GetSize()
	VBH.Note.Width = width
	VBH.Note.Height = height
	module.frame:UpdateText()
end)
module.frame:Hide() 

BHLib:FixPreloadFont(module.frame,function() 
	if VBH then
		module.frame.text:SetFont(GameFontWhite:GetFont(),11)
		module.frame:UpdateFont() 
		return true
	end
end)

function module.frame:UpdateFont()
	local font = VBH and VBH.Note and VBH.Note.FontName or BH.F.defFont
	local size = VBH and VBH.Note and VBH.Note.FontSize or 12
	local outline = VBH and VBH.Note and VBH.Note.Outline and "OUTLINE"
	local isValidFont = self.text:SetFont(font,size,outline)
	if not isValidFont then 
		self.text:SetFont(GameFontNormal:GetFont(),size,outline)
	end
end

function module.frame:UpdateText()
	if VBH.Note.ShowOnlyPersonal then
		self.text:SetText(txtWithIcons(""))
	else
		self.text:SetText(txtWithIcons(VBH.Note.Text1 or "")) 
	end
end

module.frame.background = module.frame:CreateTexture(nil, "BACKGROUND")
module.frame.background:SetColorTexture(0, 0, 0, 1)
module.frame.background:SetAllPoints()

module.frame.red_back = CreateFrame("Frame",nil,module.frame)
module.frame.red_back:SetPoint("TOPLEFT",0,0)
module.frame.red_back:SetPoint("BOTTOMRIGHT",0,0)
module.frame.red_back.b = module.frame.red_back:CreateTexture(nil, "BACKGROUND", nil, 1)
module.frame.red_back.b:SetColorTexture(1, 0, 0, .2)
module.frame.red_back.b:SetAllPoints()
module.frame.red_back.s = BHLib:Shadow(module.frame.red_back,20)
module.frame.red_back.s:SetBackdropBorderColor(1, 0, 0, .2)
module.frame.red_back:Hide()
local red_back_t = 1
module.frame.red_back:SetScript("OnShow",function()
	red_back_t = 3
end)
module.frame.red_back:SetScript("OnUpdate",function(self,tmr)
	red_back_t = red_back_t - tmr
	if red_back_t <= 0 then
		self:Hide()
		return
	end
	self.s:SetBackdropBorderColor(1, 0, 0, max(0, .4 * min(2,red_back_t)/2))
	self.b:SetColorTexture(1, 0, 0, max(0, .4 * min(2,red_back_t)/2))
end)

-- création note 
module.frame.text = module.frame:CreateFontString(nil,"ARTWORK")
module.frame.text:SetFont(BH.F.defFont, 12)
module.frame.text:SetPoint("TOPLEFT",5,-5)
module.frame.text:SetPoint("BOTTOMRIGHT",-5,5)
module.frame.text:SetJustifyH("LEFT")
module.frame.text:SetJustifyV("TOP")
module.frame.text:SetText(" ")

module.frame.buttonResize = CreateFrame("Frame",nil,module.frame)
module.frame.buttonResize:SetSize(15,15)
module.frame.buttonResize:SetPoint("BOTTOMRIGHT", 0, 0)
module.frame.buttonResize.back = module.frame.buttonResize:CreateTexture(nil, "BACKGROUND")
module.frame.buttonResize.back:SetTexture("Interface\\AddOns\\BH\\libs\\media\\Resize.tga") -- c'est bien la note
module.frame.buttonResize.back:SetAllPoints()
module.frame.buttonResize:SetScript("OnMouseDown", function(self)
	module.frame:StartSizing()
end)
module.frame.buttonResize:SetScript("OnMouseUp", function(self)
	module.frame:StopMovingOrSizing()
end)


function module.frame:Save(blackNoteID)
	VBH.Note.Text1 = (blackNoteID and VBH.Note.Black[blackNoteID] or VBH.Note.Text1 or "")

	if not blackNoteID and module.options.NoteEditBox and VBH.Note.OptionsFormatting then
	--	VBH.Note.Text1 = VBH.Note.Text1:gsub("|([Ttcr])","||%1")
	end

	if #VBH.Note.Text1 == 0 then
		VBH.Note.Text1 = " "
	end
	local txttosand = VBH.Note.Text1
	local arrtosand = {}
	local j = 1
	local indextosnd = tostring(GetTime())..tostring(math.random(1000,9999))
	for i=1,#txttosand do
		if i%220 == 0 then
			arrtosand[j]=string.sub (txttosand, (j-1)*220+1, j*220)
			j = j + 1
		elseif i == #txttosand then
			arrtosand[j]=string.sub (txttosand, (j-1)*220+1)
			j = j + 1
		end
	end
	local encounterID = VBH.Note.AutoLoad[blackNoteID or 0] or "-"
	local noteName = (blackNoteID and VBH.Note.BlackNames[blackNoteID]) or (not blackNoteID and VBH.Note.DefName) or ""

	if blackNoteID then
		VBH.Note.AutoLoad[0] = VBH.Note.AutoLoad[blackNoteID]
		VBH.Note.DefName = VBH.Note.BlackNames[blackNoteID]
		if VBH.Note.DefName then
			VBH.Note.DefName = VBH.Note.DefName:gsub("%*$","")
		end
	end

	for i=1,#arrtosand do
		BH.F.SendExMsg("multiline",indextosnd.."\t"..arrtosand[i])
	end
	--BH.F.SendExMsg("multiline_add",BH.F.CreateAddonMsg(indextosnd,encounterID,noteName))
end 

function module.frame:Clear() 
	module.options.NoteEditBox.EditBox:SetText("") 
end 

local function GetPlayerRankInRaid(unit)
	local rank = tonumber( BH.F.IsPlayerRLorOfficer(unit) or "0" )
	return rank or 0
end
local function SendNoteByEncounter(blackNoteID)
	if not IsUpdateNoteByEncounterFromMe then
		return
	end
	IsUpdateNoteByEncounterFromMe = nil
	if blackNoteID < 1 then
		blackNoteID = nil
	end
	module.frame:Save(blackNoteID)
end

function module:addonMessage(sender, prefix, ...)
	if prefix == "multiline" then
		if VBH.Note.OnlyPromoted and IsInRaid() and not BH.F.IsPlayerRLorOfficer(sender) then
			return
		end
	
		VBH.Note.LastUpdateName = sender
		VBH.Note.LastUpdateTime = time()
	
		local msgnowindex,lastnowtext = ...
		if tostring(msgnowindex) == tostring(module.db.bhmsgindex) then
			module.db.bhlasttext = module.db.bhlasttext .. lastnowtext
		else
			module.db.bhlasttext = lastnowtext
		end
		module.db.bhmsgindex = msgnowindex
		VBH.Note.Text1 = module.db.bhlasttext
		module.frame:UpdateText()
		if module.options.NoteEditBox then
			if module.options.IsMainNoteNow then
				module.options.NoteEditBox.EditBox:SetText(VBH.Note.Text1)
			end
			
			module.options.lastUpdate:SetText( L.NoteLastUpdate..": "..VBH.Note.LastUpdateName.." ("..date("%H:%M:%S %d.%m.%Y",VBH.Note.LastUpdateTime)..")" )
		end
		VBH.Note.AutoLoad[0] = nil
		if module.options.UpdatePageAfterGettingNote then
			module.options.UpdatePageAfterGettingNote()
		end
		if VBH.Note.EnableWhenReceive and not VBH.Note.enabled then
			module:Enable()
		end
		module.frame.red_back:Show()
		if type(WeakAuras)=="table" and WeakAuras.ScanEvents and type(WeakAuras.ScanEvents)=="function" then
			WeakAuras.ScanEvents("BH_NOTE_UPDATE")
		end
	elseif prefix == "multiline_add" then
		if VBH.Note.OnlyPromoted and IsInRaid() and not BH.F.IsPlayerRLorOfficer(sender) then
			return
		end
		if sender == BH.SDB.charKey then
			return
		end
		local msgIndex,noteName = ...
		if tostring(msgIndex) ~= tostring(module.db.bhmsgindex) then
			return
		end
		if noteName == "" then noteName = nil end
		VBH.Note.DefName = noteName
		if VBH.Note.SaveAllNew then
			local finded = false
			if noteName then			
				noteName = noteName:gsub("%*+$","").."*"
				for i=1,#VBH.Note.Black do
					if VBH.Note.BlackNames[i] == noteName and VBH.Note.AutoLoad[i] then
						VBH.Note.Black[i] = VBH.Note.Text1
						VBH.Note.BlackLastUpdateName[i] = sender
						VBH.Note.BlackLastUpdateTime[i] = time()
						finded = true
						break
					end
				end
			end
			if not finded then
				local newIndex = #VBH.Note.Black + 1
				VBH.Note.Black[newIndex] = VBH.Note.Text1
				VBH.Note.BlackNames[newIndex] = noteName
				VBH.Note.BlackLastUpdateName[newIndex] = sender
				VBH.Note.BlackLastUpdateTime[newIndex] = time()
				if module.options.NotesListUpdateNames then
					module.options.NotesListUpdateNames()
				end
			end
		end 
		if module.options.UpdatePageAfterGettingNote then
			module.options.UpdatePageAfterGettingNote()
		end
	elseif prefix == "multiline_req" then
		if sender and IsUpdateNoteByEncounterFromMe then
			if BH.F.IsPlayerRLorOfficer(BH.SDB.charName) == 2 then
				return
			end
			if (BH.F.IsPlayerRLorOfficer(sender) == 2) or (GetPlayerRankInRaid(sender) > GetPlayerRankInRaid(BH.SDB.charName)) or (sender < BH.SDB.charName) then
				local type = ...
				if type == "ENCOUNTER" then
					IsUpdateNoteByEncounterFromMe = nil
				end
			end
		end

	elseif prefix == "multiline_timer_sync" then
		local name = ...
		BH.F.Note_Timer(name)	
	end 
end 

local gruevent = {}

function module.main:ADDON_LOADED()
	VBH = _G.VBH
	VBH.Note = VBH.Note or {}
	VBH.Note.Black = VBH.Note.Black or {}
	VBH.Note.AutoLoad = VBH.Note.AutoLoad or {}

	if VBH.Note.Left and VBH.Note.Top then 
		module.frame:ClearAllPoints()
		module.frame:SetPoint("TOPLEFT",UIParent,"BOTTOMLEFT",VBH.Note.Left,VBH.Note.Top)
	end
	
	VBH.Note.FontSize = VBH.Note.FontSize or 12

	if VBH.Note.Width then 
		module.frame:SetWidth(VBH.Note.Width) 
	end
	if VBH.Note.Height then 
		module.frame:SetHeight(VBH.Note.Height) 
	end

	module.frame:UpdateFont()
	if VBH.Note.enabled then 
		module:Enable()
	end
	C_Timer.After(5,function()
		module.frame:UpdateFont()
	end)

	if VBH.Note.Text1 then 
		module.frame:UpdateText()
	end
	if VBH.Note.Alpha then 
		module.frame:SetAlpha(VBH.Note.Alpha/100) 
	end
	if VBH.Note.Scale then 
		module.frame:SetScale(VBH.Note.Scale/100) 
	end
	if VBH.Note.ScaleBack then
		module.frame.background:SetColorTexture(0, 0, 0, VBH.Note.ScaleBack/100)
	end
	--if VBH.Note.Outline then module.frame.text:SetFont(BH.F.defFont, 12,"OUTLINE") end
	if VBH.Note.Fix then
		module.frame:SetMovable(false)
		module.frame:EnableMouse(false)
		module.frame.buttonResize:Hide()
	else
		BH.lib.AddShadowComment(module.frame,nil,L.message)
	end
	
	if VBH.Addon.Version < 3225 then
		for i=1,12 do
			if not VBH.Note.Black[i] then
				for j=i,12 do
					VBH.Note.Black[j] = VBH.Note.Black[j+1]
				end
			end
		end
	end

	VBH.Note.BlackNames = VBH.Note.BlackNames or {}
	
	for i=1,3 do
		VBH.Note.Black[i] = VBH.Note.Black[i] or ""
	end

	VBH.Note.BlackLastUpdateName = VBH.Note.BlackLastUpdateName or {}
	VBH.Note.BlackLastUpdateTime = VBH.Note.BlackLastUpdateTime or {}
	
	VBH.Note.Strata = VBH.Note.Strata or "HIGH"
	
	module:RegisterAddonMessage()
	module:RegisterSlash()
	
	module.frame:SetFrameStrata(VBH.Note.Strata)
end

function module.main:PLAYER_LOGIN()
	if VBH.Note.enabled then
		module.frame:UpdateText()
	end
end

function module:Enable()
	VBH.Note.enabled = true
	if module.options.chkEnable then
		module.options.chkEnable:SetChecked(true)
	end
	module:RegisterEvents("PLAYER_SPECIALIZATION_CHANGED","PLAYER_LOGIN","ENCOUNTER_END","ENCOUNTER_START")
	if VBH.Note.HideOutsideRaid then
		module:RegisterEvents("GROUP_ROSTER_UPDATE")
	end
	if VBH.Note.HideInCombat then
		module:RegisterEvents('PLAYER_REGEN_DISABLED','PLAYER_REGEN_ENABLED')
	end
	if VBH.Note.ShowOnlyInRaid then
		module:RegisterEvents('ZONE_CHANGED_NEW_AREA')
	end
	module:Visibility()
end

function module:Disable()
	VBH.Note.enabled = nil
	if module.options.chkEnable then
		module.options.chkEnable:SetChecked(false)
	end
	module:UnregisterEvents('PLAYER_REGEN_DISABLED','PLAYER_REGEN_ENABLED','ZONE_CHANGED_NEW_AREA',"PLAYER_SPECIALIZATION_CHANGED","PLAYER_LOGIN","ENCOUNTER_END","ENCOUNTER_START")
	module:Visibility()
end

local Note_CombatState = false

function module:Visibility()
	local bool = true
	if not VBH.Note.enabled then
		bool = bool and false
	end
	if bool and VBH.Note.HideOutsideRaid then
		if GetNumGroupMembers() > 0 then
			bool = bool and true
		else
			bool = bool and false
		end
	end
	if bool and VBH.Note.HideInCombat then
		if Note_CombatState then
			bool = bool and false
		else
			bool = bool and true
		end
	end
	if bool and VBH.Note.ShowOnlyInRaid then
		local _,zoneType = IsInInstance()
		if zoneType == "raid" then
			bool = bool and true
		else
			bool = bool and false
		end
	end

	if bool then
		module.frame:Show()
	else
		module.frame:Hide()
	end
end

local party_uids = {'player','party1','party2','party3','party4'}
function module.main:GROUP_ROSTER_UPDATE()
	C_Timer.After(1, module.Visibility)
	if not module.options.raidnames then
		return
	end	
	for i=1,8 do gruevent[i] = 0 end
	if IsInRaid() then
		local n = GetNumGroupMembers() or 0
		local gMax = 8
		for i=1,n do
			local name,_,subgroup,_,_,class = GetRaidRosterInfo(i)
			if name and subgroup <= gMax and gruevent[subgroup] then
				gruevent[subgroup] = gruevent[subgroup] + 1
				local cR,cG,cB = BH.F.classColorNum(class)
	
				local POS = gruevent[subgroup] + (subgroup - 1) * 5
				local obj = module.options.raidnames[POS]
				
				if obj then
					name = BH.F.delUnitNameServer(name)
					local colorCode = BH.F.classColor(class)
					obj.iconText = "||c"..colorCode..name.."||r "
					obj.iconTextShift = name
					obj.html:SetText(name)
					obj.html:SetTextColor(cR, cG, cB, 1)
				end
			end
		end
	else
		for i=1,5 do
			local name = UnitName(party_uids[i])
			if name then
				gruevent[1] = gruevent[1] + 1

				local _,class = UnitClass(party_uids[i])
				local cR,cG,cB = BH.F.classColorNum(class)
	
				local POS = gruevent[1]
				local obj = module.options.raidnames[POS]
				
				if obj then
					local colorCode = BH.F.classColor(class)
					obj.iconText = "||c"..colorCode..name.."||r "
					obj.iconTextShift = name
					obj.html:SetText(name)
					obj.html:SetTextColor(cR, cG, cB, 1)
				end
			end
		end		
	end
	for i=1,8 do
		for j=(gruevent[i]+1),5 do
			local frame = module.options.raidnames[(i-1)*5+j]
			frame.iconText = ""
			frame.iconTextShift = ""
			frame.html:SetText("")
		end
	end
end 
function module.main:PLAYER_REGEN_DISABLED()
	Note_CombatState = true
	module:Visibility()
end
function module.main:PLAYER_REGEN_ENABLED()
	Note_CombatState = false
	module:Visibility()
end

function module.main:ZONE_CHANGED_NEW_AREA()
	C_Timer.After(5, module.Visibility)
end

function module.main:PLAYER_SPECIALIZATION_CHANGED()
	module.frame:UpdateText()
end


do
	local BossPhasesBossmodAdded
	local function BossPhasesBossmod()
		if BossPhasesBossmodAdded then
			return
		end
		if BigWigsLoader and type(BigWigsLoader)=='table' and BigWigsLoader.RegisterMessage then
			local r = {}
			local patt
			function r:BigWigs_Message (event, mod, key, text, ...)
				if (key == "stages") then
					if type(text)~='string' then
						return
					end

					if not patt and BigWigsAPI then
						local CL = BigWigsAPI:GetLocale("BigWigs: Common")
						if CL and CL.soon then
							patt = CL.soon:gsub("%%s","")
							if CL.soon:find("^%%s") then
								patt = patt .. "$"
							else
								patt = "^" .. patt
							end
						end
					end
					if patt and text:find( patt ) then
						return
					end

					local phase = text:match ("%d+")
					phase = tonumber (phase or "")
					if phase then
						wipe(module.db.bhencounter_time_p)
						module.db.bhencounter_time_p[phase] = GetTime()
					end
				end
			end

			BigWigsLoader.RegisterMessage (r, "BigWigs_Message")
			
			BossPhasesBossmodAdded = true
		end
	end


	function module.main:ENCOUNTER_START(encounterID, encounterName, difficultyID, groupSize)
		local updateTextReq
		local noteText = (VBH.Note.Text1 or "")..(VBH.Note.SelfText or "")
		if encounterID and encounterName then
			module.db.bhencounter_id[tostring(encounterID)] = true
			module.db.bhencounter_id[encounterName] = true
			if noteText:find("{[Ee]:([^}]+)}.-{/[Ee]}") then
				updateTextReq = true
			end
		end
		if noteText:find("{time:([0-9:]+[^{}]*)}") then
			wipe(module.db.bhencounter_time_c)
			module:RegisterTimer()
			module.db.bhencounter_time = GetTime()
			module.db.bhencounter_time_p[1] = module.db.bhencounter_time
			updateTextReq = true
			BossPhasesBossmod()
	
			if noteText:find("{time:([0-9:]+,S[^{}]*)}") then
				wipe(module.db.bhencounter_counters.SCC)
				wipe(module.db.bhencounter_counters.SCS)
				wipe(module.db.bhencounter_counters.SAA)
				wipe(module.db.bhencounter_counters.SAR)
				local anyEvent
				string_gsub(noteText,"{time:[0-9:]+,(S[^{}]*)}",function(str)
					local event,spellID,count = strsplit(":",str)
					if tonumber(count or "") and tonumber(spellID or "") and event and module.db.bhencounter_counters[event] then
						anyEvent = true
						module.db.bhencounter_counters[event][tonumber(spellID)] = 0
					end
				end)
				if anyEvent then
					wipe(module.db.bhencounter_counters_time)
					module:RegisterEvents("COMBAT_LOG_EVENT_UNFILTERED")
				end
			end
		end
		if updateTextReq then
			module.frame:UpdateText()
		end
	end
	function module.main:ENCOUNTER_END()
		wipe(module.db.bhencounter_id)
		if ((VBH.Note.Text1 or "")..(VBH.Note.SelfText or "")):find("{time:([0-9:]+[^{}]*)}") then
			module:UnregisterTimer()
			module.db.bhencounter_time = nil
			wipe(module.db.bhencounter_time_p)
			wipe(module.db.bhencounter_time_c)
	
			module:UnregisterEvents("COMBAT_LOG_EVENT_UNFILTERED")
		end
		module.frame:UpdateText()
	end
	local tmr = 0
	function module:timer(elapsed)
		tmr = tmr + elapsed
		if tmr > 1 then
			tmr = 0
			module.frame:UpdateText()
		end
	end

	module.db.bhencounter_counters_time = {}
	module.db.bhencounter_counters = {
		SCC = {},
		SCS = {},
		SAA = {},
		SAR = {},
	}
	local ECT = module.db.bhencounter_counters_time
	local SCC = module.db.bhencounter_counters.SCC
	local SCS = module.db.bhencounter_counters.SCS
	local SAA = module.db.bhencounter_counters.SAA
	local SAR = module.db.bhencounter_counters.SAR
	function module.main:COMBAT_LOG_EVENT_UNFILTERED()
		local _,event,_,_,_,_,_,_,_,_,_,spellID = CombatLogGetCurrentEventInfo()
		if event == "SPELL_CAST_SUCCESS" and SCC[spellID] then
			SCC[spellID] = SCC[spellID] + 1
			ECT[ "SCC:"..spellID..":"..SCC[spellID] ] = GetTime()
			ECT[ "SCC:"..spellID..":"..0 ] = GetTime()
		elseif event == "SPELL_CAST_START" and SCS[spellID] then
			SCS[spellID] = SCS[spellID] + 1
			ECT[ "SCS:"..spellID..":"..SCS[spellID] ] = GetTime()
			ECT[ "SCS:"..spellID..":"..0 ] = GetTime()
		elseif event == "SPELL_AURA_APPLIED" and SAA[spellID] then
			SAA[spellID] = SAA[spellID] + 1
			ECT[ "SAA:"..spellID..":"..SAA[spellID] ] = GetTime()
			ECT[ "SAA:"..spellID..":"..0 ] = GetTime()
		elseif event == "SPELL_AURA_REMOVED" and SAR[spellID] then
			SAR[spellID] = SAR[spellID] + 1
			ECT[ "SAR:"..spellID..":"..SAR[spellID] ] = GetTime()
			ECT[ "SAR:"..spellID..":"..0 ] = GetTime()
		end
	end


	function BH.F.Note_Timer(name)
		if not name then
			return
		end
		if not module.db.bhencounter_time then
			module.main:ENCOUNTER_START()
		end
		module.db.bhencounter_time_c[name] = GetTime()
	end
	function BH.F.Note_SyncTimer(name)
		if not name then
			return
		end
		BH.F.SendExMsg("multiline_timer_sync",name)
	end
end

function module:slash(arg)
	if arg == "note" or arg == "n" then
		if VBH.Note.enabled then 
			module:Disable()
		else
			module:Enable()
		end
	elseif arg == "editnote" or arg == "edit note" then
		BH.Options:Open(module.options)
	elseif arg == "note timer" then
		if module.db.bhencounter_time then
			module.main:ENCOUNTER_END()
		else
			module.main:ENCOUNTER_START()
		end
	elseif arg and arg:find("^note starttimer ") then
		local timer = arg:match("^note starttimer (.-)$")
		if timer then
			BH.F.Note_Timer(timer)
		end
	elseif arg and arg:find("^note synctimer ") then
		local timer = arg:match("^note synctimer (.-)$")
		if timer then
			BH.F.Note_SyncTimer(timer)
		end
	end
end