-- Addon: WoW-Voices (version: 11.18) 2025.07.08
-- Description: The AddOn reads the translated quest texts aloud
-- Autors: Platine, DragonArab
-- E-mail: platine.wow@gmail.com

-- *********************************************************************** --
-- It is forbidden to use or modify the code of this addon                 --
-- Any unauthorized changes to the addon may cause errors in its operation --
-- *********************************************************************** --


---------------------------------------------------------------------------------------------------------

-- A function that creates a Hash (32-bit number) of the given text
function VL_StringHash(text)
   local counter = 1;
   local pomoc = 0;
   local dlug = string.len(text);
   for i = 1, dlug, 3 do 
      counter = math.fmod(counter*8161, 4294967279);  -- 2^32 - 17: Prime!
      pomoc = (string.byte(text,i)*16776193);
      counter = counter + pomoc;
      pomoc = ((string.byte(text,i+1) or (dlug-i+256))*8372226);
      counter = counter + pomoc;
      pomoc = ((string.byte(text,i+2) or (dlug-i+256))*3932164);
      counter = counter + pomoc;
   end
   return math.fmod(counter, 4294967291) -- 2^32 - 5: Prime (and different from the prime in the loop)
end

----------------------------------------------------------------------------------------------------------------------------------------

-- Addon Variables saved in computer
local function VL_CheckVars()
   -- initialization of tables
   if (not VoicesLectorCFG) then
      VoicesLectorCFG = {};
   end
   if (not VoicesLectorSAVEnpc) then
      VoicesLectorSAVEnpc = {};
   end
   if (not VoicesLectorSAVEquest) then
      VoicesLectorSAVEquest = {};
   end
   
   -- activate the addon
   if (not VoicesLectorCFG.active) then
      VoicesLectorCFG.active = 1;
   end
   
   -- language of setting panel
   if (not VoicesLectorCFG.lang) then
      VoicesLectorCFG.lang = "EN";
   end
   
   -- read automatic
   if (not VoicesLectorCFG.automatic) then
      VoicesLectorCFG.automatic = 1;
   end
   
   -- read only once
   if (not VoicesLectorCFG.onlyOnce) then
      VoicesLectorCFG.onlyOnce = 0;
   end
   
   -- show control panel
   if (not VoicesLectorCFG.showControlPanel) then
      VoicesLectorCFG.showControlPanel = 1;
   end
   
   if (not VoicesLectorCFG.lastUse) then
      VoicesLectorCFG.lastUse = time();
   end
   
   -- show talking NPC head
   if (not VoicesLectorCFG.showNPChead) then
      VoicesLectorCFG.showNPChead = 1;
   end
   
   if (not VoicesLectorCFG.audioCTRL) then
      VoicesLectorCFG.audioCTRL = 1;
   end
   
   if (not VoicesLectorCFG.playObj) then
      VoicesLectorCFG.playObj = 0;
   end
   
   if (not VoicesLectorCFG.playGong) then
      VoicesLectorCFG.playGong = 0;
   end

   if (not VoicesLectorCFG.playToEnd) then
      VoicesLectorCFG.playToEnd = 0;
   end
   
   if (not VoicesLectorCFG.audioChannel) then
      VoicesLectorCFG.audioChannel = 4;  -- Default to MASTER channel
   end

   if (not VoicesLectorCFG.save) then
      VoicesLectorCFG.save = 1;
   end

end

----------------------------------------------------------------------------------------------------------------------------------------

function VL_SetCheckButtonState()
   if (not VL.inspected) then
      VL_Init();
   end

   VL_CheckButton1:SetChecked(VoicesLectorCFG.active==1);
   VL_CheckButton2:SetChecked(VoicesLectorCFG.automatic==1);
   VL_CheckButton3:SetChecked(VoicesLectorCFG.onlyOnce==1);
   VL_CheckButton4:SetChecked(VoicesLectorCFG.showControlPanel==1);
   VL_CheckButton5:SetChecked(VoicesLectorCFG.showNPChead==1);
   VL_CheckButton6:SetChecked(VoicesLectorCFG.audioCTRL==1);
   VL_CheckButton7:SetChecked(VoicesLectorCFG.audioCTRL==2);
   VL_CheckButton8:SetChecked(VoicesLectorCFG.audioCTRL==3);
   VL_CheckButton9:SetChecked(VoicesLectorCFG.playObj==1);
   VL_CheckButton10:SetChecked(VoicesLectorCFG.playGong==1);
   VL_CheckButton11:SetChecked(VoicesLectorCFG.playToEnd==1);

   if (VL.rT == 5) then
      VL.TextB:SetText(VL_LocalizationGetText("infoOwnFiles"));
      VL.TextB:Show();
      VL.TextD:Show();
      VL.TextE:Show();
      VL_linkButtonWWW3:Show();
   elseif ((VL.rT == 4) or (VL_license.packetCount == 0)) then
      VL.Text1:Show();
      VL.Text2:Show();
      VL.Text7:Show();
      VL_linkButtonWWW1:Show();
   elseif (VL.rT == 2) then
      VL.Text3:Show();
      VL.Text4:Show();
   elseif (VL.rT == 3) then
      VL.Text5:Show();
      VL.Text6:Show();
   end

   if ((VL.rT == 1) and VL.kT) then
      VL.Text9:Show();
      if (VL.bT and VL.TextA) then
         VL.TextA:SetText(VL.bT);
         VL.TextA:Show();
      end
      if (not VL.Text8:IsVisible()) then
         VL.TextD:Show();
      end
   end
   if (not VL.Text7:IsVisible()) then
      VL.TextE:Show();
      VL_linkButtonWWW3:Show();
   end
   
   if (C_BattleNet.GetAccountInfoByGUID(UnitGUID("player"))) then
      VL_BattleTag:SetText(C_BattleNet.GetAccountInfoByGUID(UnitGUID("player")).battleTag);
   else
      VL_BattleTag:SetText('('..VL.bT..')');
   end
end

----------------------------------------------------------------------------------------------------------------------------------------

function VL_CheckDialogChannel()                   -- checked turn off the "Dialog" channel
   if (VoicesLectorCFG.audioChannel == 2) then     -- channel "Dialog"
      UIErrorsFrame:SetTimeVisible(8);
      UIErrorsFrame:AddMessage(VL_LocalizationGetText("warningDialog1"), 1.0, 0.0, 0.0, 1.0, 10);    -- red message in error frame(
      local _font7, _size7, _37 = UIErrorsFrame:GetFont();
      UIErrorsFrame:SetFont(VL.font, 24, _37);
      UIErrorsFrame:SetWidth(800);
      PlaySound(9378, "Master");
   end
end

----------------------------------------------------------------------------------------------------------------------------------------

-- create the Blizzard setting frame
function VL_BlizzardOptions()

   -- Create main settings frame for information text and options of the addon
   local VL_Options = CreateFrame("FRAME", "VL_Options", SettingsPanel);
   if (VoicesLectorCFG.lang == 'EN') then
      VL_Options.name = VL_Localization.optionName;
   else
      VL_Options.name = VL_LocalizationGetText("optionName");
   end
--   VL_Options.refresh = function (self) VL_SetCheckButtonState() end;
--   InterfaceOptions_AddCategory(VL_Options);
   local category = Settings.RegisterCanvasLayoutCategory(VL_Options, VL_Options.name);
   Settings.RegisterAddOnCategory(category);
   VL_Options:SetScript("OnShow", function (self) VL_SetCheckButtonState() end);


   -- There is an addon icon inside the config frame 
   local VL_OptionsHeaderIcon = VL_Options:CreateTexture(nil, "OVERLAY");
   VL_OptionsHeaderIcon:SetPoint("TOPLEFT", 0, 0);
   VL_OptionsHeaderIcon:SetWidth(650);
   VL_OptionsHeaderIcon:SetHeight(80);
   if (VoicesLectorCFG.lang == 'PL') then
      VL_OptionsHeaderIcon:SetTexture(VL_Localization.mainFolder.."\\Images\\addon_icon_pl.png");
   elseif (VoicesLectorCFG.lang == 'AR') then
      VL_OptionsHeaderIcon:SetTexture(VL_Localization.mainFolder.."\\Images\\addon_icon_ar.png");
   else
      VL_OptionsHeaderIcon:SetTexture(VL_Localization.mainFolder.."\\Images\\addon_icon.png");
   end


   -- Main title of addon inside the option frame
   local VL_OptionsHeaderText = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL_OptionsHeaderText:SetFont(VL.font, 16);
   VL_OptionsHeaderText:SetWidth(600);
   VL_OptionsHeaderText:SetPoint("CENTER", VL_OptionsHeaderIcon, "CENTER", 7, 14); -- Position it above VL_OptionsVersionText
   VL_OptionsHeaderText:SetTextColor(1, 1, 1, 1); -- Set text color to white
   VL_OptionsHeaderText:SetShadowColor(0, 0, 0, 1); -- Set shadow color to black with 1.0 opacity
   VL_OptionsHeaderText:SetShadowOffset(1, -1); -- Set shadow offset
   VL_OptionsHeaderText:SetText(VL_LocalizationGetText("optionTitle"));

   -- Version and author information
   local VL_OptionsVersionText = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL_OptionsVersionText:SetFont(VL.font, 15);
   VL_OptionsVersionText:SetWidth(600);
   VL_OptionsVersionText:SetPoint("CENTER", VL_OptionsHeaderIcon, "CENTER", 7, -8);
   VL_OptionsVersionText:SetTextColor(1, 1, 1, 1); -- Set text color to white
   VL_OptionsVersionText:SetShadowColor(0, 0, 0, 1); -- Set shadow color to black with 1.0 opacity
   VL_OptionsVersionText:SetShadowOffset(1, -1); -- Set shadow offset
   if (VoicesLectorCFG.lang == 'AR') then
      VL_OptionsVersionText:SetText("|cff8080ffv"..VL.version.."|r "..VL_LocalizationGetText("versionAddon").." , "..VL_LocalizationGetText("versionByPlatine"));
   else
      VL_OptionsVersionText:SetText(VL_LocalizationGetText("versionAddon").."|cff8080ffv"..VL.version.."|r"..VL_LocalizationGetText("versionByPlatine"));
   end


   local VL_CheckButton1 = CreateFrame("CheckButton", "VL_CheckButton1", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton1:SetScript("OnClick", function(self) if (VoicesLectorCFG.active==1) then VoicesLectorCFG.active=0 else VoicesLectorCFG.active=1 end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton1:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -92);
      VL_CheckButton1.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 530, -100);
   else
      VL_CheckButton1:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -92);
      VL_CheckButton1.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -97);
   end
   VL_CheckButton1.Text:SetText("|cffffffff"..VL_LocalizationGetText("activateAddon").."|r");   -- Activate quest translations
   VL_CheckButton1.Text:SetFont(VL.font, 15);
   VL_CheckButton1.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("activateAddon").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("activateAddonDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton1.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);


   VL_BattleTag = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_BattleTag:SetFontObject(GameFontWhite);
   VL_BattleTag:SetJustifyH("LEFT"); 
   VL_BattleTag:SetJustifyV("TOP");
   VL_BattleTag:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_BattleTag:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 15, -100);
   else
      VL_BattleTag:SetPoint("TOPRIGHT", VL_Options, "TOPRIGHT", -5, -100);
   end
   VL_BattleTag:SetText(VL.bT);
   VL_BattleTag:SetFont(VL.font, 15);


   local VL_FontHeader = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_FontHeader:SetFontObject(GameFontNormal);
   VL_FontHeader:SetJustifyH("LEFT"); 
   VL_FontHeader:SetJustifyV("TOP");
   VL_FontHeader:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_FontHeader:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 525, -140);
   else
      VL_FontHeader:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 15, -140);
   end
   VL_FontHeader:SetText(VL_LocalizationGetText("fontSelectingFontHeader"));   -- Select a font header
   VL_FontHeader:SetFont(VL.font, 15);


   local VL_CurrentLang = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_CurrentLang:SetFontObject(GameFontNormal);
   VL_CurrentLang:SetJustifyH("LEFT"); 
   VL_CurrentLang:SetJustifyV("TOP");
   VL_CurrentLang:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CurrentLang:SetPoint("TOPRIGHT", VL_FontHeader, "TOPLEFT", -210, 0);
   else
      VL_CurrentLang:SetPoint("TOPLEFT", VL_FontHeader, "TOPRIGHT", 210, 0);
   end
   VL_CurrentLang:SetText(VL_LocalizationGetText("fontCurrentFont"));   -- Current language:
   VL_CurrentLang:SetFont(VL.font, 15);


   local VL_ShowCurrLang = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_ShowCurrLang:SetFontObject(GameFontWhite);
   VL_ShowCurrLang:SetJustifyH("LEFT"); 
   VL_ShowCurrLang:SetJustifyV("TOP");
   VL_ShowCurrLang:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_ShowCurrLang:SetPoint("TOPRIGHT", VL_CurrentLang, "TOPLEFT", -10, 0);
   else
      VL_ShowCurrLang:SetPoint("TOPLEFT", VL_CurrentLang, "TOPRIGHT", 10, 0);
   end
   VL_ShowCurrLang:SetText(VoicesLectorCFG.lang);   -- current language
   VL_ShowCurrLang:SetFont(VL.font, 15);


   local VL_SelectLang = CreateFrame("Frame", "VL_SelectLang", VL_Options, "UIDropDownMenuTemplate");
   VL_SelectLang:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_SelectLang:SetPoint("TOPRIGHT", VL_FontHeader, "TOPLEFT", -20, 5);
   else
      VL_SelectLang:SetPoint("TOPLEFT", VL_FontHeader, "TOPRIGHT", 20, 5);
   end
   UIDropDownMenu_SetWidth(VL_SelectLang, 115);
   UIDropDownMenu_SetText(VL_SelectLang, VL_LocalizationGetText("fontSelectFontFile"));        -- Select a language
   UIDropDownMenu_Initialize(VL_SelectLang, function(self, level, _)
      for i, lang in ipairs(VL_Languages) do
         local info = UIDropDownMenu_CreateInfo();
         info.text = lang;
--**      info.text:SetFont(VL.lang, 13);    -- missing of method SetFont
         info.value = lang;
         info.func = function(self, arg1, arg2, checked)    -- function is called when option is clicked
            VoicesLectorCFG.lang = self.value;
            VL_ShowCurrLang:SetText(self.value);            -- current language
            VL.font = VL_Localization.mainFolder.."\\Fonts\\"..self.value;
--**            VL_ShowCurrLang:SetFont(VL_Font2, 13);
            VL_ReloadButtonUI:Show();
            end;
         UIDropDownMenu_AddButton(info);
      end
   end);
   UIDropDownMenu_SetSelectedValue(VL_SelectLang, VoicesLectorCFG.lang);
   UIDropDownMenu_SetText(VL_SelectLang, VL_LocalizationGetText("fontSelectFontFile"));        -- Select a language
   

   VL_ReloadButtonUI = CreateFrame("BUTTON", nil, VL_Options, "UIPanelButtonTemplate");
   VL_ReloadButtonUI:SetWidth(135);
   VL_ReloadButtonUI:SetHeight(32);
   if ((VoicesLectorCFG.lang == 'AR') or (VoicesLectorCFG.lang == 'PL')) then
      local fo = VL_ReloadButtonUI:CreateFontString();
      fo:SetFont(VL.font, 13);
      fo:SetText(VL_LocalizationGetText("reloadButtonUI"));
      VL_ReloadButtonUI:SetFontString(fo);
   end
   VL_ReloadButtonUI:SetText(VL_LocalizationGetText("reloadButtonUI"));     -- reload the game
   VL_ReloadButtonUI:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_ReloadButtonUI:SetPoint("TOPLEFT", VL_SelectLang, "TOPLEFT", 15, 50);
   else
      VL_ReloadButtonUI:SetPoint("TOPRIGHT", VL_SelectLang, "TOPRIGHT", -15, 50);
   end
   VL_ReloadButtonUI:Hide();
   VL_ReloadButtonUI:SetScript("OnClick", function() ReloadUI(); end);
   
   
   local VL_CheckButton2 = CreateFrame("CheckButton", "VL_CheckButton2", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton2:SetScript("OnClick", function(self) if (VoicesLectorCFG.automatic==1) then VoicesLectorCFG.automatic=0; VoicesLectorCFG.onlyOnce=0; VL_CheckButton3:SetChecked(false); else VoicesLectorCFG.automatic=1 end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton2:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -172);
      VL_CheckButton2.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 425, -180);
   else
      VL_CheckButton2:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -172);
      VL_CheckButton2.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -177);
   end
   VL_CheckButton2.Text:SetText("|cffffffff"..VL_LocalizationGetText("readAutomatic").."|r");   -- Read automatically when the quest frame is opened
   VL_CheckButton2.Text:SetFont(VL.font, 15);
   VL_CheckButton2.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("readAutomatic").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("readAutomaticDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton2.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton3 = CreateFrame("CheckButton", "VL_CheckButton3", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton3:SetScript("OnClick", function(self) if (VoicesLectorCFG.onlyOnce==1) then VoicesLectorCFG.onlyOnce=0 else VoicesLectorCFG.onlyOnce=1 end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton3:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -202);
      VL_CheckButton3.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 459, -210);
   else
      VL_CheckButton3:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -202);
      VL_CheckButton3.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -207);
   end
   VL_CheckButton3.Text:SetText("|cffffffff"..VL_LocalizationGetText("readOnlyOnce").."|r");   -- Read the text only once
   VL_CheckButton3.Text:SetFont(VL.font, 15);
   VL_CheckButton3.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("readOnlyOnce").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("readOnlyOnceDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton3.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);


   local VL_CheckButton4 = CreateFrame("CheckButton", "VL_CheckButton4", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton4:SetScript("OnClick", function(self) if (VoicesLectorCFG.showControlPanel==1) then VoicesLectorCFG.showControlPanel=0 else VoicesLectorCFG.showControlPanel=1 end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton4:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -232);
      VL_CheckButton4.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 506, -240);
   else
      VL_CheckButton4:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -232);
      VL_CheckButton4.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -237);
   end
   VL_CheckButton4.Text:SetText("|cffffffff"..VL_LocalizationGetText("showControlPanel").."|r");
   VL_CheckButton4.Text:SetFont(VL.font, 15);
   VL_CheckButton4.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("showControlPanel").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("showControlPanelDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton4.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton5 = CreateFrame("CheckButton", "VL_CheckButton5", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton5:SetScript("OnClick", function(self) if (VoicesLectorCFG.showNPChead==1) then VoicesLectorCFG.showNPChead=0 else VoicesLectorCFG.showNPChead=1 end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton5:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 590, -262);
      VL_CheckButton5.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 410, -270);
   else
      VL_CheckButton5:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 40, -262);
      VL_CheckButton5.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 80, -267);
   end
   VL_CheckButton5.Text:SetText("|cffffffff"..VL_LocalizationGetText("showNpcHeadFrame").."|r");
   VL_CheckButton5.Text:SetFont(VL.font, 15);
   VL_CheckButton5.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("showNpcHeadFrame").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("showNpcHeadFrameDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton5.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_controlPanel = VL_Options:CreateTexture(nil, "OVERLAY");
   VL_controlPanel:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_controlPanel:SetPoint("TOPRIGHT", VL_CheckButton4.Text, "TOPLEFT", -10, 5);
   else
      VL_controlPanel:SetPoint("TOPLEFT", VL_CheckButton4.Text, "TOPRIGHT", 10, 5);
   end
   VL_controlPanel:SetWidth(77);
   VL_controlPanel:SetHeight(26);
   VL_controlPanel:SetTexture(VL_Localization.mainFolder.."\\Images\\panel.png");
   

   VL_ShowSettingsPanel = CreateFrame("BUTTON", nil, VL_Options, "UIPanelButtonTemplate");
   VL_ShowSettingsPanel:SetWidth(180);
   VL_ShowSettingsPanel:SetHeight(32);
   if (VoicesLectorCFG.lang == 'AR') then
      local fo = VL_ShowSettingsPanel:CreateFontString();
      fo:SetFont(VL.font, 13);
      fo:SetText(VL_LocalizationGetText("openSettingsAudio"));
      VL_ShowSettingsPanel:SetFontString(fo);
   end
   VL_ShowSettingsPanel:SetText(VL_LocalizationGetText("openSettingsAudio"));
   VL_ShowSettingsPanel:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_ShowSettingsPanel:SetPoint("TOPRIGHT", VL_Options, "TOPLEFT", 200, -170);
   else
      VL_ShowSettingsPanel:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 490, -167);
   end
   VL_ShowSettingsPanel:SetScript("OnClick", function() Settings.OpenToCategory(Settings.AUDIO_CATEGORY_ID); end);


   local VL_audioChannel = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_audioChannel:SetFontObject(GameFontWhite);
   VL_audioChannel:SetJustifyH("LEFT"); 
   VL_audioChannel:SetJustifyV("TOP");
   VL_audioChannel:ClearAllPoints();
   if (VoicesLectorCFG.lang == 'AR') then
      VL_audioChannel:SetPoint("TOPRIGHT", VL_Options, "TOPLEFT", 233, -207);
   else
      VL_audioChannel:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 410, -207);
   end
   VL_audioChannel:SetText(VL_LocalizationGetText("audioChannel"));
   VL_audioChannel:SetFont(VL.font, 15);


   local VL_AudioChannelDropdown = CreateFrame("Frame", "VL_AudioChannelDropdown", VL_Options, "UIDropDownMenuTemplate");
   if (VoicesLectorCFG.lang == 'AR') then
      VL_AudioChannelDropdown:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 5, -200);
   else
      VL_AudioChannelDropdown:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 510, -200);
   end
   UIDropDownMenu_SetWidth(VL_AudioChannelDropdown, 100);
   UIDropDownMenu_Initialize(VL_AudioChannelDropdown, function(self, level, _)
      local info = UIDropDownMenu_CreateInfo();
      info.func = function(self)
         VoicesLectorCFG.audioChannel = self.value;
         UIDropDownMenu_SetSelectedValue(VL_AudioChannelDropdown, self.value);
         if (VoicesLectorCFG.audioChannel == 2) then     -- channel "Dialog"
            if (VoicesLectorCFG.audioCTRL == 1) then
               UIErrorsFrame:SetTimeVisible(8);
               UIErrorsFrame:AddMessage(VL_LocalizationGetText("warningDialog1"), 1.0, 0.0, 0.0, 1.0, 10);    -- red message in error frame(
               local _font7, _size7, _37 = UIErrorsFrame:GetFont();
               UIErrorsFrame:SetFont(VL.font, 24, _37);
               UIErrorsFrame:SetWidth(800);
               PlaySound(9378, "Master");
            elseif (GetCVar("Sound_EnableDialog") == '0') then
               UIErrorsFrame:SetTimeVisible(8);
               UIErrorsFrame:AddMessage(VL_LocalizationGetText("warningDialog2"), 1.0, 0.0, 0.0, 1.0, 10);    -- red message in error frame               
               local _font7, _size7, _37 = UIErrorsFrame:GetFont();
               UIErrorsFrame:SetFont(VL.font, 24, _37);
               UIErrorsFrame:SetWidth(600);
               PlaySound(9378, "Master");
            end
         end
         end   -- function

      info.text, info.value = VL_LocalizationGetText("effectsChannel"), 1;
      UIDropDownMenu_AddButton(info);
      info.text, info.value = VL_LocalizationGetText("dialogChannel"), 2;
      UIDropDownMenu_AddButton(info);
      info.text, info.value = VL_LocalizationGetText("ambienceChannel"), 3;
      UIDropDownMenu_AddButton(info);
      info.text, info.value = VL_LocalizationGetText("masterChannel"), 4;
      UIDropDownMenu_AddButton(info);

      UIDropDownMenu_SetSelectedValue(VL_AudioChannelDropdown, VoicesLectorCFG.audioChannel);
      end);


   local VL_CheckButton6 = CreateFrame("CheckButton", "VL_CheckButton6", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton6:SetScript("OnClick", function(self) if (VoicesLectorCFG.audioCTRL==1) then VoicesLectorCFG.audioCTRL=0 else VoicesLectorCFG.audioCTRL=1; VL_CheckButton7:SetChecked(false); VL_CheckButton8:SetChecked(false); VL_CheckDialogChannel(); end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton6:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 245, -232);
      VL_CheckButton6.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -240);
   else
      VL_CheckButton6:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 370, -232);
      VL_CheckButton6.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 410, -237);
   end
   VL_CheckButton6.Text:SetText("|cffffffff"..VL_LocalizationGetText("turnOffAudioDialog").."|r");
   VL_CheckButton6.Text:SetFont(VL.font, 15);
   VL_CheckButton6.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("turnOffAudioDialog").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("turnOffAudioDialogDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton6.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton7 = CreateFrame("CheckButton", "VL_CheckButton7", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton7:SetScript("OnClick", function(self) if (VoicesLectorCFG.audioCTRL==2) then VoicesLectorCFG.audioCTRL=0 else VoicesLectorCFG.audioCTRL=2; VL_CheckButton6:SetChecked(false); VL_CheckButton8:SetChecked(false); end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton7:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 245, -262);
      VL_CheckButton7.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 132, -270);
   else
      VL_CheckButton7:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 370, -262);
      VL_CheckButton7.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 410, -267);
   end
   VL_CheckButton7.Text:SetText("|cffffffff"..VL_LocalizationGetText("muteNPCGreeting").."|r");
   VL_CheckButton7.Text:SetFont(VL.font, 15);
   VL_CheckButton7.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("muteNPCGreeting").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("muteNPCGreetingDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton7.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton8 = CreateFrame("CheckButton", "VL_CheckButton8", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton8:SetScript("OnClick", function(self) if (VoicesLectorCFG.audioCTRL==3) then VoicesLectorCFG.audioCTRL=0 else VoicesLectorCFG.audioCTRL=3; VL_CheckButton6:SetChecked(false); VL_CheckButton7:SetChecked(false); end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton8:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 245, -292);
      VL_CheckButton8.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 75, -300);
   else
      VL_CheckButton8:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 370, -292);
      VL_CheckButton8.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 410, -297);
   end
   VL_CheckButton8.Text:SetText("|cffffffff"..VL_LocalizationGetText("delayPlaying").."|r");
   VL_CheckButton8.Text:SetFont(VL.font, 15);
   VL_CheckButton8.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("delayPlaying").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("delayPlayingDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton8.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton9 = CreateFrame("CheckButton", "VL_CheckButton9", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton9:SetScript("OnClick", function(self) if (VoicesLectorCFG.playObj==1) then VoicesLectorCFG.playObj=0 else VoicesLectorCFG.playObj=1; end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton9:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -292);
      VL_CheckButton9.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 535, -300);
   else
      VL_CheckButton9:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -292);
      VL_CheckButton9.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -297);
   end
   VL_CheckButton9.Text:SetText("|cffffffff"..VL_LocalizationGetText("playObjectives").."|r");
   VL_CheckButton9.Text:SetFont(VL.font, 15);
   VL_CheckButton9.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("playObjectives").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("playObjectivesDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton9.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);
   
   
   local VL_CheckButton10 = CreateFrame("CheckButton", "VL_CheckButton10", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton10:SetScript("OnClick", function(self) if (VoicesLectorCFG.playGong==1) then VoicesLectorCFG.playGong=0 else VoicesLectorCFG.playGong=1; end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton10:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 450, -292);
      VL_CheckButton10.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 380, -300);
   else
      VL_CheckButton10:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 195, -292);
      VL_CheckButton10.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 230, -297);
   end
   VL_CheckButton10.Text:SetText("|cffffffff"..VL_LocalizationGetText("playObjGong").."|r");
   VL_CheckButton10.Text:SetFont(VL.font, 15);


   local VL_CheckButton11 = CreateFrame("CheckButton", "VL_CheckButton11", VL_Options, "UICheckButtonTemplate");
   VL_CheckButton11:SetScript("OnClick", function(self) if (VoicesLectorCFG.playToEnd==1) then VoicesLectorCFG.playToEnd=0 else VoicesLectorCFG.playToEnd=1; end; end);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_CheckButton11:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 620, -322);
      VL_CheckButton11.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 123, -330);
   else
      VL_CheckButton11:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 10, -322);
      VL_CheckButton11.Text:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 50, -327);
   end
   VL_CheckButton11.Text:SetText("|cffffffff"..VL_LocalizationGetText("playToEnd").."|r");
   VL_CheckButton11.Text:SetFont(VL.font, 15);
   VL_CheckButton11.Text:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT");
      GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("playToEnd").." ", false);                                -- red color, no wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:AddLine(VL_LocalizationGetText("playToEndDESC").." ", 1, 1, 1, true);                    -- white color, wrap
      getglobal("GameTooltipTextLeft2"):SetFont(VL.font, 13);
      GameTooltip:Show()   -- Show the tooltip
      end);
   VL_CheckButton11.Text:SetScript("OnLeave", function(self)
      GameTooltip:Hide()   -- Hide the tooltip
      end);


   local VL_Panel4Separator = VL_Options:CreateFontString(nil, "ARTWORK");
   VL_Panel4Separator:SetFontObject(GameFontWhite);
   VL_Panel4Separator:SetJustifyH("LEFT"); 
   VL_Panel4Separator:SetJustifyV("TOP");
   VL_Panel4Separator:ClearAllPoints();
   VL_Panel4Separator:SetPoint("CENTER", 0, -60);
   local frame = VL_Options:CreateTexture(nil, "BACKGROUND")
   frame:SetSize(684, 1)
   frame:SetPoint("CENTER", -6, -60)
   frame:SetColorTexture(0.2, 0.2, 0.2, 1)
   
   
   -- Header of packet information 
   local VL_OptionsHeaderPack = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL_OptionsHeaderPack:SetFont(VL.font, 18);
   VL_OptionsHeaderPack:SetWidth(600);
   VL_OptionsHeaderPack:SetPoint("CENTER", VL_Panel4Separator, "CENTER", 0, -20);
   VL_OptionsHeaderPack:SetText(VL_LocalizationGetText("packetTitle"));
   
   
   -- No sound pack loaded
   VL.Text1 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontRed");
   VL.Text1:SetFont(VL.font, 16);
   VL.Text1:SetWidth(600);
   VL.Text1:SetPoint("CENTER", VL_OptionsHeaderPack, "CENTER", 0, -40);
   VL.Text1:SetText(VL_LocalizationGetText("noSoundPack"));
   VL.Text1:Hide();
   
   
   -- Cannot read quest texts
   VL.Text2 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.Text2:SetFont(VL.font, 16);
   VL.Text2:SetWidth(600);
   VL.Text2:SetPoint("CENTER", VL.Text1, "CENTER", 0, -25);
   VL.Text2:SetText(VL_LocalizationGetText("noReadTexts"));
   VL.Text2:Hide();
   
   
   -- download sound pack
   VL.Text7 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL.Text7:SetFont(VL.font, 16);
   VL.Text7:SetWidth(600);
   VL.Text7:SetPoint("CENTER", VL.Text2, "CENTER", 0, -35);
   VL.Text7:SetText(VL_LocalizationGetText("toDownloadSP"));
   VL.Text7:Hide();
   
   
   -- No valid sound pack
   VL.Text3 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontRed");
   VL.Text3:SetFont(VL.font, 16);
   VL.Text3:SetWidth(600);
   VL.Text3:SetPoint("CENTER", VL_OptionsHeaderPack, "CENTER", 0, -45);
   local txtD = string.gsub(VL_LocalizationGetText("noValidPacket"), '{USER}', '|cffff00ff'..(VL_license.packetOwner or "empty")..'|r');
   VL.Text3:SetText(txtD);
   VL.Text3:Hide();
   
   
   -- License not active
   VL.Text4 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.Text4:SetFont(VL.font, 16);
   VL.Text4:SetWidth(600);
   VL.Text4:SetPoint("CENTER", VL.Text3, "CENTER", 0, -40);
   local txtD = string.gsub(txtD, '{LANDS}', '|cffff00ff'..VL_license.packetLands..'|r');
   VL.Text4:SetText(VL_LocalizationGetText("noActiveAddon"));
   VL.Text4:Hide();
   
   
   -- Illegal changes
   VL.Text5 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontRed");
   VL.Text5:SetFont(VL.font, 16);
   VL.Text5:SetWidth(600);
   VL.Text5:SetPoint("CENTER", VL_OptionsHeaderPack, "CENTER", 0, -40);
   VL.Text5:SetText(VL_LocalizationGetText("detectChanges"));
   VL.Text5:Hide();
   
   
   -- Violation of the terms
   VL.Text6 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.Text6:SetFont(VL.font, 16);
   VL.Text6:SetWidth(600);
   VL.Text6:SetPoint("CENTER", VL.Text5, "CENTER", 0, -40);
   VL.Text6:SetText(VL_LocalizationGetText("breackingTerms"));
   VL.Text6:Hide();
   
   
   -- License has expired
   VL.Text8 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.Text8:SetFont(VL.font, 16);
   VL.Text8:SetWidth(600);
   VL.Text8:SetPoint("CENTER", VL_OptionsHeaderPack, "CENTER", 0, -40);
   VL.Text8:SetText(VL_LocalizationGetText("licenseExpired"));
   VL.Text8:Hide();
   
   
   -- You have loaded a sound pack created for the player:
   VL.Text9 = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.Text9:SetFont(VL.font, 15);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.Text9:SetPoint("BOTTOMRIGHT", VL_Options, "BOTTOMRIGHT", -20, 170);
   else
      VL.Text9:SetPoint("BOTTOMLEFT", VL_Options, "BOTTOMLEFT", 10, 170);
   end
   VL.Text9:SetText(VL_LocalizationGetText("youHaveSoundPack"));
   VL.Text9:Hide();
   
   
   -- player's BattleTag
   VL.TextA = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL.TextA:SetFont(VL.font, 15);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.TextA:SetPoint("TOPRIGHT", VL.Text9, "TOPLEFT", -10, 0);
   else
      VL.TextA:SetPoint("TOPLEFT", VL.Text9, "TOPRIGHT", 10, 0);
   end
   VL.TextA:SetText("battleTag");
   VL.TextA:Hide();
   
   
   -- The package's activation date expires on:
   VL.TextB = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.TextB:SetFont(VL.font, 18);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.TextB:SetPoint("BOTTOMRIGHT", VL_Options, "BOTTOMRIGHT", -20, 140);
   else
      VL.TextB:SetPoint("BOTTOMLEFT", VL_Options, "BOTTOMLEFT", 10, 140);
   end
   VL.TextB:SetText(VL_LocalizationGetText("packageExpires"));
   VL.TextB:Hide();
   
   
   -- date of sound pack
   VL.TextC = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL.TextC:SetFont(VL.font, 15);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.TextC:SetPoint("TOPRIGHT", VL.TextB, "TOPLEFT", -10, 0);
   else
      VL.TextC:SetPoint("TOPLEFT", VL.TextB, "TOPRIGHT", 10, 0);
   end
   VL.TextC:SetText(date("%Y-%m-%d"));
   VL.TextC:Hide();
   
   
   -- sound pack info
   VL.TextD = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.TextD:SetFont(VL.font, 15);
   VL.TextD:SetWidth(650);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.TextD:SetJustifyH("RIGHT"); 
      VL.TextD:SetPoint("BOTTOMRIGHT", VL_Options, "BOTTOMRIGHT", -20, 75);
   else
      VL.TextD:SetJustifyH("LEFT"); 
      VL.TextD:SetPoint("BOTTOMLEFT", VL_Options, "BOTTOMLEFT", 10, 90);
   end
   local txtD = string.gsub(VL_LocalizationGetText("packetInfo"), '{COUNT}', '|cffff00ff'..VL_license.packetCount..'|r');
   txtD = string.gsub(txtD, '{LANG}', '|cffff00ff'..VL_license.packetType..'|r');
   txtD = string.gsub(txtD, '{LANDS}', '|cffff00ff'..VL_license.packetLands..'|r');
   VL.TextD:SetText(txtD);
   VL.TextD:Hide();
   
   
   -- more info about sound pack
   VL.TextE = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontNormal");
   VL.TextE:SetFont(VL.font, 15);
   VL.TextE:SetWidth(600);
   VL.TextE:SetPoint("CENTER", VL_Options, "CENTER", 0, -270);
   VL.TextE:SetText(VL_LocalizationGetText("detailsOnWWW"));
   VL.TextE:Hide();
   
   
   -- License of Voice Pack has expired
   VL.TextF = VL_Options:CreateFontString(nil, "OVERLAY", "GameFontWhite");
   VL.TextF:SetFont(VL.font, 16);
   VL.TextF:SetWidth(300);
   if (VoicesLectorCFG.lang == 'AR') then
      VL.TextF:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", 665, -100);
   else
      VL.TextF:SetPoint("TOPLEFT", VL_Options, "TOPLEFT", -35, -100);
   end
   VL.TextF:SetText(VL_LocalizationGetText("addonNotActive"));
   VL.TextF:Hide();
   
   
   VL_LinkFrame = CreateFrame("Frame", nil, VL_Options, "UIPanelDialogTemplate");
   VL_LinkFrame:SetWidth(305);
   VL_LinkFrame:SetHeight(120);
   VL_LinkFrame:ClearAllPoints();
   VL_LinkFrame:SetPoint("CENTER", 0, -100);
   VL_LinkFrame:SetFrameStrata("TOOLTIP");
   VL_LinkFrame.Title:SetText(VL_LocalizationGetText("linkWWWTitle"));       -- Header of the link frame
   VL_LinkFrame.Title:SetFont(VL.font, 13);
   VL_LinkFrame.Input = CreateFrame("EditBox", nil, VL_LinkFrame, "InputBoxTemplate");
   VL_LinkFrame.Input:ClearAllPoints();
   VL_LinkFrame.Input:SetPoint("TOPLEFT", VL_LinkFrame, "TOPLEFT", 20, -30);
   VL_LinkFrame.Input:SetHeight(20);
   VL_LinkFrame.Input:SetWidth(275);
   VL_LinkFrame.Input:SetAutoFocus(true);
   VL_LinkFrame.Input:SetFontObject(GameFontWhite);
   VL_LinkFrame.Input:SetText("https://wowvo.co");        -- Address of Voice Lector addon page
--VL_LinkFrame.Input:SetCursorPosition(0);
   VL_LinkFrame.Text = VL_LinkFrame:CreateFontString(nil, "ARTWORK");
   VL_LinkFrame.Text:SetFontObject(GameFontNormal);
   VL_LinkFrame.Text:SetJustifyH("CENTER"); 
   VL_LinkFrame.Text:SetJustifyV("TOP");
   VL_LinkFrame.Text:ClearAllPoints();
   VL_LinkFrame.Text:SetPoint("TOPLEFT", VL_LinkFrame, "TOPLEFT", 15, -55);
   VL_LinkFrame.Text:SetWidth(280);
   VL_LinkFrame.Text:SetText(VL_LocalizationGetText("linkCopy"));   -- Press CTRL+C to copy link address to the Clipboard
   VL_LinkFrame.Text:SetFont(VL.font, 12);
   VL_LinkFrame.ButtonOK = CreateFrame("Button",nil, VL_LinkFrame, "UIPanelButtonTemplate");
   VL_LinkFrame.ButtonOK:SetWidth(150);
   VL_LinkFrame.ButtonOK:SetHeight(20);
   local fo = VL_LinkFrame.ButtonOK:CreateFontString();
   fo:SetFont(VL.font, 13);
   fo:SetText(VL_LocalizationGetText("linkCloseFrame"));
   VL_LinkFrame.ButtonOK:SetFontString(fo);
   VL_LinkFrame.ButtonOK:SetText(VL_LocalizationGetText("linkCloseFrame"));
   VL_LinkFrame.ButtonOK:ClearAllPoints();
   VL_LinkFrame.ButtonOK:SetPoint("CENTER", 0, -38);
   VL_LinkFrame.ButtonOK:Show();
   VL_LinkFrame.ButtonOK:SetScript("OnClick", function() VL_LinkFrame:Hide(); end);
   VL_LinkFrame:Hide();
      
      
   VL_linkButtonWWW1 = CreateFrame("Button", nil, VL_Options)
   VL_linkButtonWWW1:SetSize(32, 32);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_linkButtonWWW1:SetPoint("TOPRIGHT", VL.Text7, "TOPLEFT", 10, 7);
   else
      VL_linkButtonWWW1:SetPoint("TOPLEFT", VL.Text7, "TOPRIGHT", -10, 7);
   end
   VL_linkButtonWWW1.icon = VL_linkButtonWWW1:CreateTexture()
   VL_linkButtonWWW1.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\icon_www.png")
   VL_linkButtonWWW1.icon:SetSize(32, 32);
   VL_linkButtonWWW1.icon:SetPoint("LEFT", 0, 0);
   VL_linkButtonWWW1:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
      GameTooltip:ClearLines();
      GameTooltip:AddLine(VL_LocalizationGetText("linkWWWShow"), 1, 1, 1, true);   -- white color, wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
      GameTooltip:Show() -- Show the tooltip
      end);
   VL_linkButtonWWW1:SetScript("OnLeave", function(self)
      GameTooltip:Hide() -- Hide the tooltip
      end);
   VL_linkButtonWWW1:SetScript("OnClick", function(self)
      VL_LinkFrame:Show();
      end);
   VL_linkButtonWWW1:Hide();
   
   
   VL_linkButtonWWW2 = CreateFrame("Button", nil, VL_Options)
   VL_linkButtonWWW2:SetSize(32, 32);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_linkButtonWWW2:SetPoint("TOPRIGHT", VL.Text8, "TOPLEFT", 10, 0);
   else
      VL_linkButtonWWW2:SetPoint("TOPLEFT", VL.Text8, "TOPRIGHT", -20, 0);
   end
   VL_linkButtonWWW2.icon = VL_linkButtonWWW2:CreateTexture()
   VL_linkButtonWWW2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\icon_www.png")
   VL_linkButtonWWW2.icon:SetSize(32, 32);
   VL_linkButtonWWW2.icon:SetPoint("LEFT", 0, 0);
   VL_linkButtonWWW2:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
      GameTooltip:ClearLines();
      GameTooltip:AddLine(VL_LocalizationGetText("linkWWWShow"), 1, 1, 1, true);   -- white color, wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
      GameTooltip:Show() -- Show the tooltip
      end);
   VL_linkButtonWWW2:SetScript("OnLeave", function(self)
      GameTooltip:Hide() -- Hide the tooltip
      end);
   VL_linkButtonWWW2:SetScript("OnClick", function(self)
      VL_LinkFrame:Show();
      end);
   VL_linkButtonWWW2:Hide();
      
      
   VL_linkButtonWWW3 = CreateFrame("Button", nil, VL_Options)
   VL_linkButtonWWW3:SetSize(32, 32);
   if (VoicesLectorCFG.lang == 'AR') then
      VL_linkButtonWWW3:SetPoint("TOPRIGHT", VL.TextE, "TOPLEFT", 10, 0);
   else
      VL_linkButtonWWW3:SetPoint("TOPLEFT", VL.TextE, "TOPRIGHT", -20, 0);
   end
   VL_linkButtonWWW3.icon = VL_linkButtonWWW3:CreateTexture()
   VL_linkButtonWWW3.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\icon_www.png")
   VL_linkButtonWWW3.icon:SetSize(32, 32);
   VL_linkButtonWWW3.icon:SetPoint("LEFT", 0, 0);
   VL_linkButtonWWW3:SetScript("OnEnter", function(self)
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
      GameTooltip:ClearLines();
      GameTooltip:AddLine(VL_LocalizationGetText("linkWWWShow"), 1, 1, 1, true);   -- white color, wrap
      getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
      GameTooltip:Show() -- Show the tooltip
      end);
   VL_linkButtonWWW3:SetScript("OnLeave", function(self)
      GameTooltip:Hide() -- Hide the tooltip
      end);
   VL_linkButtonWWW3:SetScript("OnClick", function(self)
      VL_LinkFrame:Show();
      end);
   VL_linkButtonWWW3:Hide();
   
end

----------------------------------------------------------------------------------------------------------------------------------------

function VL_PlayIcon_OnEnter(nr)
   if (nr == 0) then       -- voice file is not available (red icon)
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\red_play_icon.png");
      VL.playIcon:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("voiceFileNotAvailable").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon:SetScript("OnClick", nil);

      VL.playIcon2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\red_play_icon.png");
      VL.playIcon2:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("voiceFileNotAvailable").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon2:SetScript("OnClick", nil);
   elseif (nr == 2) then       -- voice file is not found (blue icon)
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\blue_play_icon.png");
      VL.playIcon:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("voiceFileNotFound").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon:SetScript("OnClick", nil);

      VL.playIcon2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\blue_play_icon.png");
      VL.playIcon2:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("voiceFileNotFound").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon2:SetScript("OnClick", nil);
   elseif (nr == 3) then       -- channel "Dialog" is disabled and play on the channel "Dialog"
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\blue_play_icon.png");
      VL.playIcon:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("channelDialogIsDisabled").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon:SetScript("OnClick", nil);

      VL.playIcon2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\blue_play_icon.png");
      VL.playIcon2:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("channelDialogIsDisabled").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon2:SetScript("OnClick", nil);
   else                    -- voice file is available (white icon, nr=1)
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\white_play_icon.png");
      VL.playIcon:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("playIconTitle").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon:SetScript("OnClick", function() 
         if (VL.handle) then
            StopSound(VL.handle);
         end
         VL_StartSoundPlaying();
         end);
         
      VL.playIcon2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\white_play_icon.png");
      VL.playIcon2:SetScript("OnEnter", function(self)
         GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
         GameTooltip:ClearLines();
         GameTooltip:AddLine(VL_LocalizationGetText("playIconTitle").." ", 1, 1, 1, true);   -- white color, wrap
         getglobal("GameTooltipTextLeft1"):SetFont(VL.font, 13);
         GameTooltip:Show() -- Show the tooltip
         end);
      VL.playIcon2:SetScript("OnClick", function() 
         if (VL.handle) then
            StopSound(VL.handle);
         end
         VL_StartSoundPlaying();
         end);
   end
end

-------------------------------------------------------------------------------------------------------

-- events captured by addon
local function VL_onEvent(self, event, name, ...)
   if (event=="ADDON_LOADED" and name==VL_Localization.addonName) then
      self:UnregisterEvent("ADDON_LOADED");
      self:RegisterEvent("QUEST_DETAIL");
      self:RegisterEvent("QUEST_PROGRESS");
      self:RegisterEvent("QUEST_COMPLETE");
      self:RegisterEvent("GOSSIP_SHOW");
      VL_CheckVars();
      if (VoicesLectorCFG.lang == 'EN') then
         VL.font = "Fonts\\FRIZQT__.ttf";
      else
         VL.font = VL_Localization.mainFolder.."\\Fonts\\font_"..string.lower(VoicesLectorCFG.lang)..".ttf";
      end
      VL_BlizzardOptions();
      
      VL.readed = {};   -- table for readed quests (to function only once)
      VL.player = {};
      VL.player.race = UnitRace("player");
      VL.player.class = UnitClass("player");
      VL.player.sex = UnitSex("player");     -- 1:neutral,  2:male,  3:female
      VL.inspected = false;
      VL.CounterD = 0;
      VL.rT = 0;
      VL.fT = 0;
      
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.playIcon = CreateFrame("Button", nil, DUIQuestFrame);
         VL.playIcon:SetPoint("TOPLEFT", DUIQuestFrame.FrontFrame, "TOPLEFT", -15, 0);
      elseif VL_isImmersion() then      -- addon Immersion is active
         VL.playIcon = CreateFrame("Button", nil, ImmersionFrame.TalkBox);
         VL.playIcon:SetPoint("TOPLEFT", ImmersionFrame.TalkBox, "TOPLEFT", 150, -102);
      elseif VL_isStoryLine() then      -- addon Story is active
         VL.playIcon = CreateFrame("Button", nil, Storyline_NPCFrameChat);
         VL.playIcon:SetPoint("TOPLEFT", Storyline_NPCFrameChat, "TOPLEFT", 7, -5);
      else
         VL.playIcon = CreateFrame("Button", nil, QuestFrame);
         if (string.sub(GetBuildInfo(),1,1) == '4') then     -- Patch 4.4.x (Cataclysm)
            VL.playIcon:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", -35, -44);
         else
            VL.playIcon:SetPoint("TOPLEFT", QuestFrame, "TOPLEFT", 60, -26);
         end
      end
      VL.playIcon:SetSize(32, 32);
      VL.playIcon.icon = VL.playIcon:CreateTexture(nil, "OVERLAY");
      VL.playIcon.icon:ClearAllPoints();
      VL.playIcon.icon:SetPoint("CENTER", 0, 0);
      VL.playIcon.icon:SetWidth(32);
      VL.playIcon.icon:SetHeight(32);
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\red_play_icon.png");
      VL.playIcon:SetScript("OnLeave", function(self)
         GameTooltip:Hide() -- Hide the tooltip
         end);
      VL.playIcon:Show();

      VL.playIcon2 = CreateFrame("Button", nil, QuestMapFrame.QuestsFrame.DetailsFrame.RewardsFrameContainer.RewardsFrame);
      VL.playIcon2:SetPoint("TOPRIGHT",QuestMapFrame.QuestsFrame.DetailsFrame.RewardsFrameContainer.RewardsFrame ,"TOPRIGHT", -10, -15);
      VL.playIcon2:SetSize(32, 32);
      VL.playIcon2.icon = VL.playIcon2:CreateTexture(nil, "OVERLAY");
      VL.playIcon2.icon:ClearAllPoints();
      VL.playIcon2.icon:SetPoint("CENTER", 0, 0);
      VL.playIcon2.icon:SetWidth(32);
      VL.playIcon2.icon:SetHeight(32);
      VL.playIcon2.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\red_play_icon.png");
      VL.playIcon2:SetScript("OnLeave", function(self)
         GameTooltip:Hide() -- Hide the tooltip
         end);
      VL.playIcon2:Show();
      hooksecurefunc("QuestMapFrame_ShowQuestDetails", VL_PrepareVoice);
      QuestMapFrame:HookScript("OnHide", VL_onHideQuestFrame);
      QuestMapFrame.QuestsFrame.DetailsFrame.BackFrame.BackButton:HookScript("OnClick", VL_onHideQuestFrame);
      
      -- Animation---------------------------------------------------------------------------------------------------------
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.portraitFrame = CreateFrame("Frame", nil, DUIQuestFrame);
         VL.portraitFrame:SetPoint("TOPRIGHT", DUIQuestFrame, "TOPLEFT", 0, -72);
         VL.portraitFrame:SetSize(140, 140);
      else
         VL.portraitFrame = CreateFrame("Frame", nil, QuestFrame);
         if (string.sub(GetBuildInfo(),1,1) == '4') then     -- Patch 4.4.x (Cataclysm)
            VL.portraitFrame:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", 149, -221);
            VL.portraitFrame:SetSize(180, 180);
         else
            VL.portraitFrame:SetPoint("BOTTOMLEFT", QuestFrame, "BOTTOMRIGHT", 0, 40);
            VL.portraitFrame:SetSize(200, 200);
         end
      end
      VL.portraitFrame:SetFrameLevel(1000);
      VL.portraitFrame:SetMovable(true);
      VL.portraitFrame:EnableMouse(true);
      VL.portraitFrame:RegisterForDrag("LeftButton");
      VL.portraitFrame:SetScript("OnDragStart", VL.portraitFrame.StartMoving);
      VL.portraitFrame:SetScript("OnDragStop", VL.portraitFrame.StopMovingOrSizing);
      -- Create close button
      VL.portraitFrame.closeButton = CreateFrame("Button", nil, VL.portraitFrame, "UIPanelCloseButton");
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.portraitFrame.closeButton:SetPoint("TOPRIGHT", 5, 25);
      else
         VL.portraitFrame.closeButton:SetPoint("TOPRIGHT", 5, 5);
      end
      VL.portraitFrame.closeButton:SetFrameLevel(VL.portraitFrame:GetFrameLevel() + 10);  -- Set close button to display above other elements
      VL.portraitFrame.closeButton:SetScript("OnClick", function() VL.portraitFrame:Hide(); end);
      VL.portraitFrame:Hide();
   
      VL.portraitFrame.model = CreateFrame("DressUpModel", nil, VL.portraitFrame);
      -- Position the model frame within the portrait frame
      VL.portraitFrame.model:SetPoint("TOPLEFT", 6, -5);
      VL.portraitFrame.model:SetPoint("BOTTOMRIGHT", -4, 10);
   
      -- Adjust the model scale
      VL.portraitFrame.model:SetModelScale(1)
   
      -- Create a background frame with a border
      VL.portraitFrame.bg = CreateFrame("Frame", nil, VL.portraitFrame, "BackdropTemplate");
      VL.portraitFrame.bg:SetPoint("TOPLEFT", -5, 5);
      VL.portraitFrame.bg:SetPoint("BOTTOMRIGHT", 5, -45);
      VL.portraitFrame.bg:SetBackdrop({
         bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
         edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
         tile = true,
         tileSize = 32,
         edgeSize = 32,
         insets = { left = 11, right = 12, top = 12, bottom = 11 },
         });
      VL.portraitFrame.bg:SetBackdropColor(0, 0, 0, 0.8);
   
      -- Add a title bar
      VL.portraitFrame.titleBar = VL.portraitFrame:CreateTexture(nil, "ARTWORK");
      VL.portraitFrame.titleBar:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header");
      if (string.sub(GetBuildInfo(),1,1) == '4') then     -- Patch 4.4.x (Cataclysm)
         VL.portraitFrame.titleBar:SetPoint("TOP", 0, 30);
         VL.portraitFrame.titleBar:SetSize(200, 58);
      else
         VL.portraitFrame.titleBar:SetPoint("TOP", 0, 35);
         VL.portraitFrame.titleBar:SetSize(300, 68);
      end
   
      -- Create a frame to hold the quest title and NPC name
      VL.portraitFrame.infoFrame = CreateFrame("Frame", nil, VL.portraitFrame);
      VL.portraitFrame.infoFrame:SetPoint("TOPLEFT", VL.portraitFrame, "BOTTOMLEFT", 0, -10);
      VL.portraitFrame.infoFrame:SetPoint("TOPRIGHT", VL.portraitFrame, "BOTTOMRIGHT", 0, -10);
      VL.portraitFrame.infoFrame:SetHeight(40);
   
      -- Add a title
      VL.portraitFrame.title = VL.portraitFrame:CreateFontString(nil, "ARTWORK", "GameFontNormal");
      VL.portraitFrame.title:SetPoint("TOP", VL.portraitFrame.titleBar, 0, -14);
      VL.portraitFrame.title:SetText(VL_Localization.addonName);
   
      -- Add the NPC name
      VL.portraitFrame.npcName = VL.portraitFrame.infoFrame:CreateFontString(nil, "ARTWORK", "GameFontNormal");
      VL.portraitFrame.npcName:SetPoint("CENTER", 0, 25);
      VL.portraitFrame.npcName:SetJustifyH("CENTER");
      VL.portraitFrame.npcName:SetTextColor(1.6, 0.6, 0.6);
      
      -- Add the quest title
      VL.portraitFrame.questTitle = VL.portraitFrame.infoFrame:CreateFontString(nil, "ARTWORK", "GameFontNormal");
      VL.portraitFrame.questTitle:SetPoint("CENTER", 0, 7);
      VL.portraitFrame.questTitle:SetJustifyH("CENTER");
      VL.portraitFrame.questTitle:SetTextColor(1, 0.82, 0);
      VL.portraitFrame.questTitle:SetFont(VL.font, 12);
      -- end Animation-----------------------------------------------------------------------------------------------------------
   
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.controlPanel = CreateFrame("Frame", nil, DUIQuestFrame);
         VL.controlPanel:SetPoint("TOPLEFT", DUIQuestFrame, "TOPLEFT", 48, -5);
      elseif VL_isImmersion() then      -- addon Immersion is active
         VL.controlPanel = CreateFrame("Frame", nil, ImmersionFrame.TalkBox);
         VL.controlPanel:SetPoint("TOPLEFT", ImmersionFrame.TalkBox, "TOPLEFT", 190, -110);
      elseif VL_isStoryLine() then      -- addon StoryLine is active
         VL.controlPanel = CreateFrame("Frame", nil, Storyline_NPCFrameChat);
         VL.controlPanel:SetPoint("TOPLEFT", Storyline_NPCFrameChat, "TOPLEFT", 45, -8);
      else
         VL.controlPanel = CreateFrame("Frame", nil, QuestFrame);
         VL.controlPanel:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", 0, 22);
      end
      VL.controlPanel:SetWidth(64);
      VL.controlPanel:SetHeight(24);
      
      VL.controlPanel.tex = VL.controlPanel:CreateTexture();
      VL.controlPanel.tex:SetAllPoints();
      VL.controlPanel.tex:SetColorTexture(0, 0, 0, 1);

      VL.controlPanel.play = CreateFrame("Button", nil, VL.controlPanel);
      VL.controlPanel.play:SetSize(16, 16);
      VL.controlPanel.play:SetPoint("TOPLEFT", VL.controlPanel, "TOPLEFT", 5, -4);
      VL.controlPanel.play.icon = VL.controlPanel.play:CreateTexture(nil, "OVERLAY");
      VL.controlPanel.play.icon:ClearAllPoints();
      VL.controlPanel.play.icon:SetPoint("CENTER", 0, 0);
      VL.controlPanel.play.icon:SetWidth(16);
      VL.controlPanel.play.icon:SetHeight(16);
      VL.controlPanel.play.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\play_icon.png");
      
      VL.controlPanel.pause = CreateFrame("Button", nil, VL.controlPanel);
      VL.controlPanel.pause:SetSize(16, 16);
      VL.controlPanel.pause:SetPoint("TOPLEFT", VL.controlPanel, "TOPLEFT", 25, -4);
      VL.controlPanel.pause.icon = VL.controlPanel.pause:CreateTexture(nil, "OVERLAY");
      VL.controlPanel.pause.icon:ClearAllPoints();
      VL.controlPanel.pause.icon:SetPoint("CENTER", 0, 0);
      VL.controlPanel.pause.icon:SetWidth(16);
      VL.controlPanel.pause.icon:SetHeight(16);
      VL.controlPanel.pause.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\pause_icon.png");
      
      VL.controlPanel.stop = CreateFrame("Button", nil, VL.controlPanel);
      VL.controlPanel.stop:SetSize(16, 16);
      VL.controlPanel.stop:SetPoint("TOPLEFT", VL.controlPanel, "TOPLEFT", 45, -4);
      VL.controlPanel.stop.icon = VL.controlPanel.stop:CreateTexture(nil, "OVERLAY");
      VL.controlPanel.stop.icon:ClearAllPoints();
      VL.controlPanel.stop.icon:SetPoint("CENTER", 0, 0);
      VL.controlPanel.stop.icon:SetWidth(16);
      VL.controlPanel.stop.icon:SetHeight(16);
      VL.controlPanel.stop.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\stop_icon.png");
      VL.controlPanel:Hide();
      
      QuestFrame:HookScript("OnShow", VL_onShowQuestFrame);
      QuestFrame:HookScript("OnHide", VL_onHideQuestFrame);

      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         DUIQuestFrame:HookScript("OnHide", VL_onHideQuestFrame);
      elseif VL_isImmersion() then      -- addon Immerion is active
         ImmersionFrame.TalkBox:HookScript("OnHide", VL_onHideQuestFrame);
      elseif VL_isStoryLine() then      -- addon StoryLine is active
         Storyline_NPCFrame:HookScript("OnHide", VL_onHideQuestFrame);
      end

      print("|cffffff00"..VL_Localization.addonName.."  ver. "..VL.version.." - "..(VL_LocalizationGetText("started") or VL_Localization.started));
      VL_Init();
   elseif ((event == "QUEST_DETAIL") or (event == "QUEST_PROGRESS") or (event == "QUEST_COMPLETE")) then
      VL.lastEvent = VL.event or "NONE";
      VL.event = event;
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.playIcon:Show();
         VL_onShowQuestFrame();
      elseif VL_isImmersion() then      -- addon Immerion is active
--         VL.playIcon:Show();
         VL_onShowQuestFrame();
      elseif VL_isStoryLine() then      -- addon StoryLine is active
         VL.playIcon:Show();
         VL_onShowQuestFrame();
      end
   elseif (event == "GOSSIP_SHOW") then
      VL.event = event;
      if (VL_isDUIQuestFrame() or VL_isImmersion() or VL_isStoryLine()) then      -- addon DialogueUI or Immersion or DtoryLine is active
         VL.playIcon:Hide();
      end
   end
end

-------------------------------------------------------------------------------------------------------

function VL_PrepareVoice()
   VL.questID = QuestMapFrame.DetailsFrame.questID;
   VL.soundIndex = VL.rT;
   if (VL.questID and VL_table[VL.questID] and VL_table[VL.questID][VL.soundIndex]) then   -- Details
      VL_PlayIcon_OnEnter(1);       -- voice file is available (white icon)
   else
      VL_PlayIcon_OnEnter(0);       -- voice file is not available (red icon)
   end
end

-------------------------------------------------------------------------------------------------------

function VL_SetControlPanel(nr)
   VL.controlPanel.play.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\play_icon.png");
   VL.controlPanel.pause.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\pause_icon.png");
   VL.controlPanel.stop.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\stop_icon.png");
   if (nr == 1) then
      VL.controlPanel.play.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\play2_icon.png");
   elseif (nr == 2) then
      VL.controlPanel.pause.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\pause2_icon.png");
   elseif (nr == 3) then
      VL.controlPanel.stop.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\stop2_icon.png");
   end
end

-------------------------------------------------------------------------------------------------------

local function VL_npcMuteDialog()
   local NPCtable = VL_MutedSounds[VL.npcID];
   if (NPCtable) then
      for _, soundID in pairs(NPCtable) do
         MuteSoundFile(soundID);
      end
   end
end

-------------------------------------------------------------------------------------------------------

function VL_DeleteBadLetters(BT)
   if (not BT) then
      return '';
   end
   local out = '';
   for i=1, #BT, 1 do
      local chr = string.sub(BT,i,i);
      if (chr >= '0' and  chr<= '9') or (chr >= 'A' and  chr<= 'Z') or (chr >= 'a' and  chr<= 'z') or chr=='#' then
         out = out .. chr;
      end
   end
   return out;
end

-------------------------------------------------------------------------------------------------------

function VL_StartSoundPlaying()
   if (VL.npcID and (VL.npcID > 0) and (VoicesLectorCFG.audioCTRL == 2)) then
      VL_npcMuteDialog();     -- mute NPC dialogs (greating and farewell)
   end
   local soundChannel;
   if VoicesLectorCFG.audioChannel == 1 then
      soundChannel = "SFX";
   elseif VoicesLectorCFG.audioChannel == 2 then
      soundChannel = "Dialog";
   elseif VoicesLectorCFG.audioChannel == 3 then
      soundChannel = "Ambience";
   else
      soundChannel = "Master";
   end
   local file13;
   if ((VL.rT == 5) and VL_table[VL.questID] and VL_table[VL.questID][VL.soundIndex] and VL_table[VL.questID][VL.soundIndex].file) then
      file13 = VL_table[VL.questID][0].."\\"..VL_table[VL.questID][VL.soundIndex].file;
   elseif (VL.questID and VL_table[VL.questID] and VL_table[VL.questID][0]) then
      local digits = string.sub('0000000000'..VL_StringHash(VL_DeleteBadLetters(VL.bT)..":"..VL.questID),-10);
      file13 = VL_table[VL.questID][0].."\\Q" .. digits .. VL.types[VL.soundIndex] .. ".ogg";
   else
      file13 = "Q0000000000X.ogg";
   end
   VL.willPlay, VL.handle = PlaySoundFile(VL_Localization.mainFolder.."\\VoicePack\\"..file13, soundChannel);
   if (VL.willPlay == nil) then
      if ((VoicesLectorCFG.audioChannel == 2) and ((VoicesLectorCFG.audioCTRL == 1) or (GetCVar("Sound_EnableDialog") == "0"))) then     -- play on channel "Dialog" and channel "Dialog" is off
         VL_PlayIcon_OnEnter(3);
      else
         VL_PlayIcon_OnEnter(2);
      end
      return;
   end
   
   ------------------------------------------------------------------------------------------------------------------------------
   VL.controlPanel:ClearAllPoints();
   if ((VoicesLectorCFG.showNPChead == 1) and (VL.portraitFrame:IsVisible())) then
      VL.controlPanel:SetParent(VL.portraitFrame);
      VL.controlPanel:SetPoint("TOPLEFT", VL.portraitFrame, "TOPLEFT", 68, 2);
      -- Animate the model
      VL.portraitFrame.model:SetCreature(VL.npcID);
      -- Set up the model to show only the head
      VL.portraitFrame.model:SetPortraitZoom(0.8);    -- size scale of head
      VL.portraitFrame.model:SetPosition(-0.4, 0.1, -0.05);    -- zoom, horizontal, vertical
      -- Set a timer to loop the animation
      -- Set a timer to loop the talking animation with random pauses
      VL.portraitFrame.model.animationTimer = C_Timer.NewTicker(0.1, function()
            if (not VL.portraitFrame.model.nextAnimationTime or (GetTime() >= VL.portraitFrame.model.nextAnimationTime)) then
               local animationID = 60;  -- Use talking animations 60, 61, or 62
               VL.portraitFrame.model:SetAnimation(animationID, 2);
               -- Set a random pause time between 0.5 and 2 seconds
               local pauseTime = math.random(10, 30) / 10;
               VL.portraitFrame.model.nextAnimationTime = GetTime() + pauseTime;
            end
         end);
      if (QuestModelScene:IsVisible() and not VL.portraitFrame.moved) then     -- portraitFrame need move 
         local point, relativeTo, relativePoint, xOfs, yOfs = VL.portraitFrame:GetPoint(1);
         VL.portraitFrame.xOfs = xOfs;          -- remember last position
         VL.portraitFrame.yOfs = yOfs;
         VL.portraitFrame:ClearAllPoints();
         VL.portraitFrame:SetPoint("TOPLEFT", QuestModelScene, "TOPRIGHT", 3, 0);
         VL.portraitFrame.moved = true;
      end
      VL.portraitFrame:Show();
      if VL_isImmersion() then      -- addon Immersion is active
         VL.controlPanel:SetParent(ImmersionFrame.TalkBox);
         VL.controlPanel:SetPoint("TOPLEFT", ImmersionFrame.TalkBox, "TOPLEFT", 190, -110);
      elseif VL_isStoryLine() then  -- addon StoryLine is active
         VL.controlPanel:SetParent(Storyline_NPCFrameChat);
         VL.controlPanel:SetPoint("TOPLEFT", Storyline_NPCFrameChat, "TOPLEFT", 45, -8);
      end
   else
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.controlPanel:SetParent(DUIQuestFrame);
         VL.controlPanel:SetPoint("TOPLEFT", DUIQuestFrame, "TOPLEFT", 48, -5);
      elseif VL_isImmersion() then      -- addon Immersion is active
--         VL.controlPanel:SetParent(ImmersionFrame.TalkBox);
         VL.controlPanel:SetPoint("TOPLEFT", ImmersionFrame.TalkBox, "TOPLEFT", 190, -110);
      elseif VL_isStoryLine() then  -- addon StoryLine is active
         VL.controlPanel:SetParent(Storyline_NPCFrame);
         VL.controlPanel:SetPoint("TOPLEFT", Storyline_NPCFrame, "TOPLEFT", 190, -110);
      elseif (QuestMapFrame:IsVisible()) then  -- QuestMapFrame is opened
         VL.controlPanel:SetParent(QuestMapFrame.QuestsFrame.DetailsFrame.RewardsFrameContainer.RewardsFrame);
         VL.controlPanel:SetPoint("TOPRIGHT", QuestMapFrame.QuestsFrame.DetailsFrame.RewardsFrameContainer.RewardsFrame, "TOPRIGHT", -50, -20);
      else
         VL.controlPanel:SetParent(QuestFrame);
         VL.controlPanel:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", 0, 22);
      end
   end
   ------------------------------------------------------------------------------------------------------------------------------
   
   if (VL.willPlay) then
      VL.soundTimer = time();
      VL.playingNow = true;
      if (VL.rT == 5) then
         VL.soundDuration = VL_table[VL.questID][VL.soundIndex].duration;
      else
         VL.soundDuration = VL_table[VL.questID][VL.soundIndex];
      end
      C_Timer.After(VL.soundDuration, VL_DurationEnd);
      if (VoicesLectorCFG.showControlPanel == 1) then
         VL.controlPanel:Show();
      end
      VL.readed[tostring(VL.questID).."-"..VL.soundIndex] = true;
      VL_SetControlPanel(1);
      VL.controlPanel.play:SetScript("OnClick", function() StopSound(VL.handle); VL_StartSoundPlaying(); end);
      VL.controlPanel.pause:SetScript("OnClick", function() StopSound(VL.handle,200); VL.playingNow = false; VL_SetControlPanel(2); VL_StopTheAnimation(); end);
      VL.controlPanel.stop:SetScript("OnClick", function() StopSound(VL.handle,200); VL.playingNow = false; VL_SetControlPanel(3); VL_StopTheAnimation(); end);
   else           -- file not exists
      VL.playIcon.icon:SetTexture(VL_Localization.mainFolder.."\\Images\\red_play_icon.png");
   end
end

-------------------------------------------------------------------------------------------------------

-- play voices, when quest frame is displayed
function VL_onShowQuestFrame()
   if (VoicesLectorCFG.active>0) then
      if (VoicesLectorCFG.audioCTRL==1) then
         SetCVar("Sound_EnableDialog", 0);
      end
      VL_Priority();
      local npcGUID = UnitGUID("npc");
      if (npcGUID) then
         local _, _, _, _, _, npcID = strsplit("-", npcGUID);
         if (npcID) then
            VL.npcID = tonumber(npcID);
         else
            VL.npcID = 0
         end
      else
         VL.npcID = 0;
      end
      if (not VL.inspected) then
         VL_Init();
      end
      VL.portraitFrame:Hide();
      VL.controlPanel:Hide();
      VL.playIcon:Hide();
      if (VL.portraitFrame.moved) then     -- restore previous position on portraitFrame
         VL.portraitFrame:ClearAllPoints();
         if (string.sub(GetBuildInfo(),1,1) == '4') then     -- Patch 4.4.x (Cataclysm)
            VL.portraitFrame:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", VL.portraitFrame.xOfs, VL.portraitFrame.yOfs);
         else
            VL.portraitFrame:SetPoint("BOTTOMLEFT", QuestFrame, "BOTTOMRIGHT", VL.portraitFrame.xOfs, VL.portraitFrame.yOfs);
         end
         VL.portraitFrame.moved = false;
      end
      if (VoicesLectorCFG.automatic == 1) then
         if (VL.event ~= 'GOSSIP_SHOW') then
            VL.playIcon:Show();
         end
         if (VoicesLectorCFG.audioCTRL==3) then
            C_Timer.After(2.5, VL_ServiceVoices);
         elseif ((VoicesLectorCFG.audioCTRL==2) and (VL.fT == 0)) then
            C_Timer.After(2.5, VL_ServiceVoices);
         else
            C_Timer.After(0.3, VL_ServiceVoices);
         end
         VL.fT = 1;
      else
         VL_ServiceVoices();
      end
      C_Timer.After(0.1, VL_SetNPCNameQuestTitle);
   else
      VL.playIcon:Hide();
   end
end

-------------------------------------------------------------------------------------------------------------------

function VL_SetNPCNameQuestTitle()
   -- Set the NPC name and quest title
   VL.portraitFrame.npcName:SetText(UnitName("npc") or "");
   VL.portraitFrame.questTitle:SetText(GetTitleText() or "");
--   if (VL.event == "QUEST_PROGRESS") then
--      VL.portraitFrame.questTitle:SetText(QuestProgressTitleText:GetText() or GetTitleText() or "");
--   else
--      VL.portraitFrame.questTitle:SetText(QuestInfoTitleHeader:GetText() or GetTitleText() or "");
--   end
end

-------------------------------------------------------------------------------------------------------------------

function VL_ServiceVoices()
   if ((VoicesLectorCFG.active>0) and (((VL.rT==1) and VL.kT) or (VL.rT==5))) then
      if ((VL.questID == GetQuestID()) and (VL.lastEvent == VL.event) and VL.playingNow) then
         return;
      end
      if (VL.playingNow) then
         StopSound(VL.handle,300);
      end
      VL.playingNow = false;
      VL.questID = GetQuestID();
      VL.soundIndex = VL.rT;
      if (VL.event == "QUEST_PROGRESS") then
         VL.soundIndex = VL.rT*2;
      elseif (VL.event == "QUEST_COMPLETE") then
         VL.soundIndex = VL.rT+2;
      end
      if (VL.questID and VL_table[VL.questID] and VL_table[VL.questID][VL.soundIndex]) then   -- Details
         VL_PlayIcon_OnEnter(1);       -- voice file is available (white icon)
         VL_SetControlPanel(0);
         if ((VoicesLectorCFG.onlyOnce == 1) and (not VL.readed[tostring(VL.questID).."-"..VL.soundIndex])) then      -- play only once
            if (VoicesLectorCFG.automatic == 1) then
               VL_StartSoundPlaying();
            end
         else
            if ((VoicesLectorCFG.automatic == 1) and (VoicesLectorCFG.onlyOnce == 0)) then
               VL_StartSoundPlaying();
            end
         end
      else
         VL_PlayIcon_OnEnter(0);              -- voice file is not available (red icon)
         if ((VoicesLectorCFG.save > 0) and (VL.rT == 1)) then   -- save new dates
            local VL_mapID = C_Map.GetBestMapForUnit("player");
            if (VL_mapID) then
               local nr_poz, nr_poz2 = string.find(","..VL_license.allLandsID.."," , ","..VL_mapID..",");    -- gdy nie znalazł, jest: nil
               if (nr_poz and (nr_poz2>0)) then
                  local VL_mapINFO = C_Map.GetMapInfo(VL_mapID);
                  local race;
                  if (VL.npcID and (VL.npcID > 0)) then
                     race = UnitRace(VL.npcID) or "";
                  else
                     race = "";
                  end
                  if (VL_mapINFO) then
                     VoicesLectorSAVEnpc[tostring(VL.questID).."-"..VL.types[VL.soundIndex]] = tostring(VL.npcID).."@"..(QuestFrameTitleText:GetText() or '?').."@"..race.."@"..(UnitSex("target") or "").."@"..(VL_mapID or "").."@"..VL_mapINFO.name.."@"..VL_mapINFO.mapType.."@"..VL_mapINFO.parentMapID;
                  else
                     VoicesLectorSAVEnpc[tostring(VL.questID).."-"..VL.types[VL.soundIndex]] = tostring(VL.npcID).."@"..(QuestFrameTitleText:GetText() or '?').."@"..race.."@"..(UnitSex("target") or "").."@"..(VL_mapID or "").."@@@";
                  end
                  if (VL.event == "QUEST_COMPLETE") then
                     VoicesLectorSAVEquest[tostring(VL.questID).."-"..VL.types[VL.soundIndex]] = GetRewardText();
                  elseif (VL.event == "QUEST_PROGRESS") then
                     VoicesLectorSAVEquest[tostring(VL.questID).."-"..VL.types[VL.soundIndex]] = GetProgressText();
                  else
                     VoicesLectorSAVEquest[tostring(VL.questID).."-"..VL.types[VL.soundIndex]] = GetQuestText();
                     VoicesLectorSAVEquest[tostring(VL.questID).."-T"] = GetTitleText();
                     VoicesLectorSAVEquest[tostring(VL.questID).."-P"] = UnitName("player")..'@'..UnitRace("player")..'@'..UnitClass("player");
                  end
               end
            end
         end
      end
      if (VL.event ~= 'GOSSIP_SHOW') then
         VL.playIcon:Show();
      end
   else
      VL_PlayIcon_OnEnter(0);          -- voice file is not available (red icon)
   end
end

-------------------------------------------------------------------------------------------------------

function VL_StopTheAnimation()
   -- Stop the animation loop
   if VL.portraitFrame.model.animationTimer then
      VL.portraitFrame.model.animationTimer:Cancel();
   end
   -- Set the idle animation
   VL.portraitFrame.model:SetAnimation(0);
end

-------------------------------------------------------------------------------------------------------

function VL_DurationEnd()        -- sound duration has passed away
   if (VL.playingNow and (time()>VL.soundTimer+VL.soundDuration-1.5)) then
      VL.playingNow = false;
      VL.controlPanel:Hide();
      VL_StopTheAnimation();
      if (((VL.soundIndex == 1) or (VL.soundIndex == 5)) and (VoicesLectorCFG.playObj==1)) then   -- read Objectives
         if (VL.questID and VL_table[VL.questID] and VL_table[VL.questID][4]) then   -- Objectives
            local soundChannel;
            if VoicesLectorCFG.audioChannel == 1 then
               soundChannel = "SFX";
            elseif VoicesLectorCFG.audioChannel == 2 then
               soundChannel = "Dialog";
            elseif VoicesLectorCFG.audioChannel == 3 then
               soundChannel = "Ambience";
            else
               soundChannel = "Master";
            end
            local delay = 1.5;
            if (VoicesLectorCFG.playGong==1) then     -- play gong
               C_Timer.After(delay, function() PlaySoundFile(VL_Localization.mainFolder.."\\VoicePack\\gong.mp3", soundChannel); end);
               delay = delay + 1.5;      -- duration of gong sound
            end
            local file4;
            if ((VL.rT == 5) and VL_table[VL.questID] and VL_table[VL.questID][VL.soundIndex] and VL_table[VL.questID][4].file) then
               file4 = VL_table[VL.questID][0].."\\"..VL_table[VL.questID][4].file;
            else
               local digits = string.sub('0000000000'..VL_StringHash(VL_DeleteBadLetters(VL.bT)..":"..VL.questID),-10);
               file4 = VL_table[VL.questID][0].."\\Q" .. digits .. "D.ogg";
            end
            VL_StopTheAnimation();
            C_Timer.After(delay, function() VL.willPlay, VL.handle = PlaySoundFile(VL_Localization.mainFolder.."\\VoicePack\\"..file4, soundChannel); end);
            VL.playingNow = true;
         end
      end
   end
end

-------------------------------------------------------------------------------------------------------

function VL_onHideQuestFrame()
   if (VoicesLectorCFG.active>0) then
      if (VL.playingNow and VL.handle and (VoicesLectorCFG.playToEnd == 0)) then
         StopSound(VL.handle,300);
         VL.playingNow = false;
      end
      VL_StopTheAnimation();
      if (VL.npcID and (VL.npcID > 0) and (VoicesLectorCFG.audioCTRL == 2)) then
         C_Timer.After(0.1, VL_npcMuteDialog);     -- mute NPC farewell dialogs
      end
      if VL_isDUIQuestFrame() then      -- addon DialogueUI is active
         VL.controlPanel:Hide();
         VL.portraitFrame:Hide();
      end
      if (VL.controlPanel:GetParent() == QuestMapFrame.QuestsFrame.DetailsFrame.RewardsFrameContainer.RewardsFrame) then
         VL.controlPanel:Hide();
      end
   end
end

-------------------------------------------------------------------------------------------------------

function VL_isDUIQuestFrame()             -- check if DialogueUI is loaded
   if (DUIQuestFrame ~= nil) then         -- addon DialogueUI is active
      return true;
   else
      return false;
   end
end

-------------------------------------------------------------------------------------------------------

function VL_isImmersion()
   if (ImmersionFrame ~= nil ) then       -- check if Immersion is loaded
      return true;                        -- addon Immersion is loaded
   else   
      return false;
   end
end
   
-------------------------------------------------------------------------------------------------------

function VL_isStoryLine()
   if (Storyline_NPCFrame ~= nil ) then   -- check if StoryLine is loaded
      return true;                        -- addon StoryLine is loaded
   else
      return false;
   end
end

-------------------------------------------------------------------------------------------------------------------

-- General Variables
VL = CreateFrame("Frame");
local GetAddOnMetadata = (C_AddOns and C_AddOns.GetAddOnMetadata) or GetAddOnMetadata;
VL.version = GetAddOnMetadata(VL_Localization.addonName, "Version");
VL:SetScript("OnEvent", VL_onEvent);
VL:RegisterEvent("ADDON_LOADED");
VL.types = { [1] = 'A', [2] = 'B', [3] = 'C', [4] = 'D' };

