/*
	Stargate for GarrysMod10
	Copyright (C) 2007  aVoN

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

local PANEL = {};
-- To store the mousepos accross sessions
PANEL.Data = {}

--################# Init @aVoN
function PANEL:Init()
	self:SetSize(700,160);
	self:SetMinimumSize(700,160);
	self:SetPos(10,10);
	--self:Center(); -- Center is gay!
	self.LastEntity = nil;
	-- Keyboard/Mouse behaviour
	self.Entity = self.Entity or NULL;
	-- VGUI Elements
	self.VGUI = {
		TitleLabel = vgui.Create("DLabel",self),
		AddressPanel = vgui.Create("SAddressPanel",self),
		AddressLabel = {
			vgui.Create("DLabel",self),
			vgui.Create("DLabel",self), -- Black background/Shadow
		},
		AddressSelect = vgui.Create("SAddressSelect",self),
		AddressSelectLabel = {
			vgui.Create("DLabel",self),
			vgui.Create("DLabel",self), -- Black background/Shadow
		},
		NameTextEntry = vgui.Create("DTextEntry",self),
		NameLabel = vgui.Create("DLabel",self),
		PrivateImage = vgui.Create("DImage",self),
		PrivateCheckbox = vgui.Create("DCheckBoxLabel",self),
	}
	-- The topic of the whole frame
	self.VGUI.TitleLabel:SetText("Stargate");
	self.VGUI.TitleLabel:SetPos(30,7);
	--###### Set Address
	-- The Topic of this section
	for i=1,2 do
		local mul = (i-1);
		self.VGUI.AddressLabel[i]:SetText("Gate Settings");
		self.VGUI.AddressLabel[i]:SetPos(30-mul*2,35-mul*2);
		self.VGUI.AddressLabel[i]:SetTextColor(Color(255*mul,255*mul,255*mul,255));
	end
	
	-- Our AddressPanel (Where we set Addresses with)
	self.VGUI.AddressPanel:SetPos(30,60);
	self.VGUI.AddressPanel.OnAddressSet = function(e,address)
		if((self.AlphaTime or 0)+0.3 < CurTime()) then -- Avoids the VGUI sending "SetGateAddress" everytime we open it!
			e:SetGateAddress(address);
		end
	end
	--###### Name
	-- Name Label
	self.VGUI.NameLabel:SetPos(30,103);
	self.VGUI.NameLabel:SetText("Name:");
	
	-- Name TextEntry
	self.VGUI.NameTextEntry:SetPos(75,103);
	self.VGUI.NameTextEntry:SetWide(110);
	self.VGUI.NameTextEntry:SetTooltip("You can name your Stargate to make it easier to search");
	self.VGUI.NameTextEntry.OnTextChanged = function(TextEntry)
		local s = TextEntry:GetValue();
		local e = self.Entity;
		local search = self.VGUI.AddressSelect;
		-- Do this within a timer to avoid constant calling of the concommand as soon as someont types in something
		timer.Remove("_StarGate.SetNameTime");
		timer.Create("_StarGate.SetNameTime",1,1,
			function()
				if(ValidEntity(e)) then
					e:SetGateName(s);
				end
			end
		);
	end
	
	--###### Private
	-- The Private Image
	self.VGUI.PrivateImage:SetPos(30,129);
	self.VGUI.PrivateImage:SetSize(16,16);
	self.VGUI.PrivateImage:SetImage("gui/silkicons/shield");
	
	-- The Private Checkbox
	self.VGUI.PrivateCheckbox:SetPos(75,130);
	self.VGUI.PrivateCheckbox:SetText("Private");
	local tip = "Private Stargates are unsearchable, but they can still be called!";
	self.VGUI.PrivateCheckbox:SetTooltip(tip);
	self.VGUI.PrivateCheckbox.Label:SetTooltip(tip); -- Workaround/Fix
	self.VGUI.PrivateCheckbox.Button.ConVarChanged = function(CheckBox)
		local b = util.tobool(CheckBox:GetChecked());
		if(ValidEntity(self.Entity)) then
			self.Entity:SetPrivate(b);
		end
	end
	
	--###### Select Address
	-- The topic
	for i=1,2 do
		local mul = (i-1);
		self.VGUI.AddressSelectLabel[i]:SetText("Dialling");
		self.VGUI.AddressSelectLabel[i]:SetPos(250-mul*2,35-mul*2);
		self.VGUI.AddressSelectLabel[i]:SetTextColor(Color(255*mul,255*mul,255*mul,255));
	end
	-- Our AddressSelect Panel (Where we dial Addresses from)
	self.VGUI.AddressSelect:SetPos(250,60);
	self.VGUI.AddressSelect.OnDial = function(e,address,mode)
		e:DialGate(address,mode);
		self:SetVisible(false);
	end
	self.VGUI.AddressSelect.OnAbort = function(e)
		e:AbortDialling();
		self:SetVisible(false);
	end
	self:RegisterHooks();
end

--################# Register Hooks @aVoN
function PANEL:RegisterHooks()
	-- This is necessary: Everytime we set this window visible, we will update the address panel and any other necessary object
	self._SetVisible = self.SetVisible;
	self.SetVisible = function(self,b)
		if(b) then
			if(self.OnOpen) then 
				local ret = self:OnOpen();
				if(ret ~= nil) then return ret end;
			end
		else
			if(self.OnClose) then 
				local ret = self:OnClose();
				if(ret ~= nil) then return ret end;
			end
		end
		self._SetVisible(self,b);
	end
end

--################# Open Hook @aVoN
function PANEL:OnOpen()
	self:SetKeyBoardInputEnabled(true);
	self:SetMouseInputEnabled(true);
	self.AlphaTime = CurTime(); -- For the FadeIn/Out
	self.FadeOut = nil;
	self:SetAlpha(1); -- We will fade in!
	self.VGUI.AddressSelect:RefreshList(true);
	if(self.Data.MouseX and self.Data.MouseY) then
		gui.SetMousePos(self.Data.MouseX,self.Data.MouseY);
	end
end

--################# Close Hook @aVoN
function PANEL:OnClose()
	self:SetKeyBoardInputEnabled(false);
	self:SetMouseInputEnabled(false);
	self.AlphaTime = CurTime(); -- For the FadeIn/Out
	self.FadeOut = true;
	return false; -- Override default fadeout
end

--################# To what Entity to we belong to? @aVoN
function PANEL:SetEntity(e)
	self.Entity = e;
	self.VGUI.AddressSelect:SetEntity(e);
	self.VGUI.AddressPanel:SetEntity(e);
	self.VGUI.NameTextEntry:SetText(e:GetGateName());
	self.VGUI.PrivateCheckbox:SetValue(e:GetPrivate());
end

--################# Perform the layout @aVoN
function PANEL:PerformLayout()
	--####### Save Width/Heigth
	local w,h = self:GetSize();
	self.VGUI.AddressSelect:SetSize(w-(250+10),h-(60+10));
end

--################# Think @aVoN
function PANEL:Think()
	local x,y = gui.MousePos();
	if(x ~= ScrW()/2 and y ~= ScrH() and x > 1 and y > 1) then -- Prevents some resnapping bugs
		self.Data.MouseX,self.Data.MouseY = x,y;
	end
end

--################# Paint @aVoN
function PANEL:Paint()
	-- Fade in!
	local alpha = math.Clamp(CurTime() - (self.AlphaTime or 0),0,0.20)*5;
	if(self.FadeOut) then
		alpha = 1-alpha;
		if(alpha == 0) then
			self:_SetVisible(false);
			self.FadeOut = nil;
		end
	end
	draw.RoundedBox(10,0,0,self:GetWide(),self:GetTall(),Color(16,16,16,160*alpha));
	self:SetAlpha(alpha*255);
	return true;
end

vgui.Register("SControlePanel",PANEL,"Frame");




--##################################
--###### The DHD Panel (And Later for a mobile DHD)
--##################################

local data = PANEL.Data; -- To store the mousepos accross sessions (And sync it with the main Panel)
local PANEL = table.Copy(PANEL);
PANEL.Data = data;

--################# Init @aVoN
function PANEL:Init()
	self:SetSize(440,160);
	self:SetMinimumSize(440,160);
	self:SetPos(10,10); -- No Center because I'm planing making it able to dial a DHD by just clicking with the mouse on it
	--self:Center();
	self.LastEntity = nil;
	-- Keyboard/Mouse behaviour
	self.Entity = self.Entity or NULL;
	-- VGUI Elements
	self.VGUI = {
		TitleLabel = vgui.Create("DLabel",self),
		AddressSelect = vgui.Create("SAddressSelect",self),
		AddressSelectLabel = {
			vgui.Create("DLabel",self),
			vgui.Create("DLabel",self), -- Black background/Shadow
		},
	}
	-- The topic of the whole frame
	self.VGUI.TitleLabel:SetText("Stargate");
	self.VGUI.TitleLabel:SetPos(30,7);
	self.VGUI.TitleLabel:SetWide(200);
	--###### Select Address
	-- The topic
	for i=1,2 do
		local mul = (i-1);
		self.VGUI.AddressSelectLabel[i]:SetText("Dialling");
		self.VGUI.AddressSelectLabel[i]:SetPos(10-mul*2,35-mul*2);
		self.VGUI.AddressSelectLabel[i]:SetTextColor(Color(255*mul,255*mul,255*mul,255));
	end
	-- Our AddressSelect Panel (Where we dial Addresses from)
	self.VGUI.AddressSelect:SetPos(10,60);
	self.VGUI.AddressSelect.OnDial = function(e,address,mode)
		e:DialGate(address,mode);
		self:SetVisible(false);
	end
	self.VGUI.AddressSelect.OnAbort = function(e)
		e:AbortDialling();
		self:SetVisible(false);
	end
	self.VGUI.AddressSelect.OnTextChanged = function(AddressSelect)
		if(self.OnTextChanged) then self.OnTextChanged(AddressSelect) end;
	end
	-- This is necessary: Everytime we set this window visible, we will update the address panel and any other necessary object
	self:RegisterHooks();
end

--################# Sets a value to the address field @aVoN
function PANEL:SetText(text)
	self.VGUI.AddressSelect:SetText(text);
end

--################# Gets an address @aVoN
function PANEL:GetValue()
	return self.VGUI.AddressSelect:GetValue();
end

--################# Perform the layout @aVoN
function PANEL:PerformLayout()
	--####### Save Width/Heigth
	local w,h = self:GetSize();
	self.VGUI.AddressSelect:SetSize(w-20,h-(60+10));
end

--################# To what Entity to we belong to? @aVoN
function PANEL:SetEntity(e)
	self.Entity = e;
	self.VGUI.AddressSelect:SetEntity(e);
end

vgui.Register("SControlePanelDHD",PANEL,"Frame");