-- window.lua by hummel (www.modhoster.de)
Window = {};

function Window.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function Window:load(xmlFile)
	self.windows_open = {}
	self.windows_open[0] = false -- Tuer links
	self.windows_open[1] = false -- heckscheibe
	self.windows_open[2] = false -- tuer rechts
	self.windows_open[3] = false -- dachluke
	self.windows_open[4] = false -- frontscheibe
		self.windows_open[5] = false -- rul
	self.rotationPartwindows = {}
	
	self.bindings = {}
	self.bindings[0] = InputBinding.BigXWINDOW0
	self.bindings[1] = InputBinding.BigXWINDOW1
	self.bindings[2] = InputBinding.BigXWINDOW2
	self.bindings[3] = InputBinding.BigXWINDOW3
	self.bindings[4] = InputBinding.BigXWINDOW4
	self.bindings[5] = InputBinding.BigXWINDOW5
	
	self.toggleWindow = SpecializationUtil.callSpecializationsFunction("toggleWindow");
	
	for k,state in pairs(self.windows_open) do
	  local rotationPartNodewindow = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, string.format("vehicle.window%d#index", k)));
	  if rotationPartNodewindow ~= nil then
        self.rotationPartwindows[k] = {};
        self.rotationPartwindows[k].node = rotationPartNodewindow;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, string.format("vehicle.rotationPartwindow%d#minRot", k)));
        self.rotationPartwindows[k].minRot = {};
        self.rotationPartwindows[k].minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartwindows[k].minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartwindows[k].minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, string.format("vehicle.window%d#maxRot", k)));
        self.rotationPartwindows[k].maxRot = {};
        self.rotationPartwindows[k].maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartwindows[k].maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartwindows[k].maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPartwindows[k].rotTime = Utils.getNoNil(getXMLString(xmlFile, string.format("vehicle.window%d#rotTime", k)), 2)*1000;
        self.rotationPartwindows[k].touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, string.format("vehicle.window%d#touchRotLimit", k)), 10));
	  end;	  
	end
end;

function Window:keyEvent(unicode, sym, modifier, isDown)	 
end;



function Window:mouseEvent(posX, posY, isDown, isUp, button)
end;

function Window:draw(dt)

end

function Window:update(dt)
	if self.isEntered then
		for k,state in pairs(self.windows_open) do
			if InputBinding.hasEvent(self.bindings[k]) then
				self:toggleWindow(k, not self.windows_open[k])
			end
		end	
	end		

	for k,state in pairs(self.windows_open) do
		if self.rotationPartwindows[k] ~= nil then
		   local x, y, z = getRotation(self.rotationPartwindows[k].node);
		   local rot = {x,y,z};
		   local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartwindows[k].maxRot, self.rotationPartwindows[k].minRot, 3, self.rotationPartwindows[k].rotTime, dt, not self.windows_open[k]);
		   setRotation(self.rotationPartwindows[k].node, unpack(newRot));
		end;
	end


end;

function Window:readStream(streamId, connection)  
  for k,state in pairs(self.windows_open) do
    self.windows_open[k] = streamReadBool(streamId);
  end
end


function Window:writeStream(streamId, connection)
  for k,state in pairs(self.windows_open) do
    streamWriteBool(streamId, self.windows_open[k]);
  end
end   

function Window:toggleWindow(key, open, noEventSend)
  if noEventSend ~= true then
		WindowEvent.sendEvent(self, key, open);
	end;
	self.windows_open[key] = open
end

function Window:onEnter()
end;

function Window:onLeave()
end;

function Window:delete()
end;


WindowEvent = {};
WindowEvent_mt = Class(WindowEvent, Event);

InitEventClass(WindowEvent, "WindowEvent");

function WindowEvent:emptyNew() 
    local self = Event:new(WindowEvent_mt );
    self.className="WindowEvent";
    return self;
end;

function WindowEvent:new(vehicle, key, open)
    self.vehicle = vehicle;
    self.key = key
	self.open = open
    return self;
end;

function WindowEvent:readStream(streamId, connection) 
    local id = streamReadInt32(streamId);
	self.vehicle = networkGetObject(id);
    self.key = streamReadInt32(streamId);
	self.open = streamReadBool(streamId);
    self:run(connection); 
end;

function WindowEvent:writeStream(streamId, connection)   
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteInt32(streamId, self.key);
    streamWriteBool(streamId, self.open );     
end;

function WindowEvent:run(connection)  
    self.vehicle:toggleWindow(self.key, self.open, true);
	if not connection:getIsServer() then  
		g_server:broadcastEvent(WindowEvent:new(self.vehicle, self.key, self.open), nil, connection, self.object);
	end;
end;

function WindowEvent.sendEvent(vehicle, key, open, noEventSend) 
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then 
			g_server:broadcastEvent(WindowEvent:new(vehicle, key, open), nil, nil, vehicle);
		else 
			g_client:getServerConnection():sendEvent(WindowEvent:new(vehicle, key, open));			
		end;
	end;
end;