Doors = {};

-- Function to load the doors.
function epsilonScript.LoadDoors()	
	-- Check if any saved door data exists.
	if ( !file.Exists( "epsilonScript/Doors/" .. game.GetMap() .. ".txt" ) ) then return end;
	
	local Data = glon.decode( file.Read( "epsilonScript/Doors/" .. game.GetMap() .. ".txt" ) );
	Doors = Data;
	
	local k, v;
	local k2, v2;
	local k3, v3;
	
	-- Loop the data table.
	for k, v in pairs( Data ) do
		-- Set the saved doors data.
		for k2, v2 in pairs( ents.FindInSphere( v.Pos, 0.1 ) ) do
			if ( v2:IsDoor() and v2:GetPos() == v.Pos ) then
				v2.Name = v.Name;
				v2.Cost = v.Cost;
				v2.Owner = v.Owner or "";
			end;
		end;
		
		-- Check if any doors don't have data, set it.
		for k3, v3 in pairs( ents.GetAll() ) do
			if ( v3:IsDoor() and v3.Name == nil and v3.Cost == nil and v3.Owner == nil ) then
				v3.Name = "For Sale";
				v3.Cost = 100;
				v3.Owner = "Unowned";
			end;
		end;
	end;
end;

local function AddNewDoor( ply, cmd, args )
	if ( !ply:IsAdmin() ) then return end;
	
	local Entity = ply:TraceDoor( 90 );
	
	local Tbl = {};
	Tbl.Name = args[ 1 ];
	Tbl.Cost = tonumber( args[ 2 ] );
	Tbl.Owner = args[ 3 ];
	Tbl.Pos = Entity:GetPos();
	
	Doors[ #Doors + 1 ] = Tbl;
	
	-- Save the data.
	local Data = glon.encode( Doors );
	file.Write( "epsilonScript/Doors/" .. game.GetMap() .. ".txt", Data );
end;
concommand.Add( "eps_addnewdoor", AddNewDoor );
epsilonScript.AddChatCmd( "newdoor", "eps_addnewdoor" );

function GM:ShowSpare2( ply )
	local tr = ply:EyeTrace( 80 );
	
	if ( tr.Entity:IsValid() and tr.Entity:IsPlayer() ) then
		ply:ConCommand( "eps_givemoneymenu" );
	end;

	local Door = ply:TraceDoor( 90 );
	
	if ( !Door ) then return end;
	if ( Door.Owner == "Unownable" ) then ply:SendNotify( "Can't buy/own this door!" ) return end;
	
	if ( !ply:OwnsDoor( Door ) and Door.Owner == "Unowned" ) then
		-- Send the door cost.
		umsg.Start( "RDC", ply );
			umsg.Long( Door.Cost );
		umsg.End();
		
		ply:ConCommand( "eps_buydoormenu" ) return;
	elseif ( ply:OwnsDoor( Door ) ) then
		ply:ConCommand( "eps_doorproperties" ) return;
	elseif( Door.Owner != "Unowned" ) then
		ply:ChatPrint( "Door is sold already!" ) return;
	end;
end;

local function UpdateDoorInfo( ply, cmd, args )
	local Entity = ents.GetByIndex( tonumber( args[ 1 ] ) );
	
	if ( Entity:IsValid() and Entity:IsDoor() ) then
		if ( !ply.DoorData[ Entity ] ) then ply.DoorData[ Entity ] = { [ "Name" ] = "loldunno" } end;
		
		if ( Entity.Name == nil ) then Entity.Name = "" end;
		if ( ply.DoorData[ Entity ].Name != Entity.Name ) then
			umsg.Start( "UpdateDoor", ply );
				umsg.Entity( Entity );
				umsg.String( Entity.Name );
			umsg.End();
			
			ply.DoorData[ Entity ].Name = Entity.Name;
		end;
	end;
end;
concommand.Add( "eps_updatedoorinfo", UpdateDoorInfo );

-- Function to buy a door.
local function BuyDoor( ply, cmd, args )
	local Door = ents.GetByIndex( tonumber( args[ 1 ] ) );
	local DoorCost = Door.Cost;
	local plyMoney = ply:GetCharInfo( "Money" );
	
	-- Can't afford it?
	if ( !ply:CanAfford( DoorCost ) ) then
		ply:SendNotify( "You need another " .. DoorCost - plyMoney .. epsilonScript.Config:Get( "Currency" ) .. "!" ) return;
	end;
	
	ply:SetCharInfo( "Money", plyMoney - DoorCost );
	ply:UpdateMoney()
	Door.Owner = ply;
	Door.Name = ply:Name();
end
concommand.Add( "eps_buydoor", BuyDoor );

local function SellDoor( ply, cmd, args )
	local Door = ents.GetByIndex( tonumber( args[ 1 ] ) );
	
	if ( ply:OwnsDoor( Door ) ) then
		Door.Owner = "Unowned";
		Door.Name = "For Sale";
		ply:SendNotify( "Door Sold!" );
		ply:SetCharInfo( "Money", ply:GetCharInfo( "Money" ) + Door.Cost );
		ply:UpdateMoney()
	end;
end;
concommand.Add( "eps_selldoor", SellDoor );

local function NameDoor( ply, cmd, args )
	local NewName = args[ 1 ];
	local Door = ents.GetByIndex( tonumber( args[ 2 ] ) );
	
	if ( ply:OwnsDoor( Door ) ) then
		Door.Name = NewName;
	end;
end;
concommand.Add( "eps_namedoor", NameDoor );

function _R.Player:OwnsDoor( Ent )
	local Entity = self:TraceDoor( 90 );
	
	if ( Entity.Owner == self ) then
		return true;
	end;
	
	return false;
end;