--
-- InteractiveControlPanel
-- Specialization for InteractiveControlPanel
--
-- @author:      Manuel Leithner
-- @date:        20/10/10
-- @version:    v2.0
-- @history:    v1.0 - initial implementation
--                v2.0 - Converted to LS2011
--

InteractiveControlPanel = InteractiveControlBase.newSpecialization();

function InteractiveControlPanel.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;

function InteractiveControlPanel:load(savegame)

--source(Utils.getFilename("InteractiveComponentInterface.lua", self.baseDirectory));
    
    self.detachPosition = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanel#detachPosition"));
    self.controlPanel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanel#index"));
    if self.detachPosition == nil then
        self.detachPosition = getParent( self.controlPanel )
    end
    
    self.attacherVehicleCopy = nil;
    
    self.infoBar = {};
    self.infoBar.posX = 0.4;
    self.infoBar.posY = 0.9359;
    
    self.infoBar.width = 0.3156;
    self.infoBar.hud = Overlay:new("icInfobar", Utils.getFilename("Textures/interactiveControl_info.dds", self.baseDirectory), self.infoBar.posX, self.infoBar.posY, self.infoBar.width, 0.0526);
    
    self.interactiveObjects = {};            
    self.isControlingActive = false

    self.isDetachAllowed = Utils.overwrittenFunction(self.isDetachAllowed, InteractiveControlPanel.isDetachAllowed)
    
end;

function InteractiveControlPanel:postLoad(xmlFile)
    setVisibility( self.controlPanel, false )
end

function InteractiveControlPanel:update(dt)
    if self:getIsActive() and not ( self.isControlingActive ) then    
        for k,v in pairs(self.interactiveObjects) do
            if      self.isClient 
                    and self:getIsActiveForInput(false) 
                    and not self:hasInputConflictWithSelection() 
                    and InteractiveControlBase.hasInputEvent( v.id ) then
                if v.isLocalOnly == nil or not v.isLocalOnly then
                    InteractiveControlPanelEvent.sendEvent(self, k, noEventSend);    
                end;
                v:doAction()
            end
            v:update(dt);
        end
    end
end

function InteractiveControlPanel:draw()    
    if self:getIsActive() and not ( self.isControlingActive ) then    
        for _,v in pairs(self.interactiveObjects) do
            if v.showHelp and InputBinding[v.id] ~= nil then
                local text=""
                if v.isOpen then
                    text = string.format(v.offMessage, v.name);
                else
                    text = string.format(v.onMessage, v.name);
                end;
                g_currentMission:addHelpButtonText(text, InputBinding[v.id]);
            end;
        
            v:draw();
        end;
    end;
end;


function InteractiveControlPanel:onAttach(attacherVehicle)
    self.attacherVehicleCopy = attacherVehicle;
    if type( self.attacherVehicleCopy.controlPanels ) == "table" then
        local wasSuccessful = InteractiveControlPanel.addControlPanel(self.attacherVehicleCopy, self);
        if wasSuccessful then
            setVisibility( self.controlPanel, true )
        end
    end;    
end;

function InteractiveControlPanel:isDetachAllowed( superFunc )
    if self.attacherVehicleCopy ~= nil and self.attacherVehicleCopy.isMouseActive then
        return false
    end
    
    if superFunc ~= nil then
        return superFunc(self)
    end

    return true
end

function InteractiveControlPanel:onDetach()
    if self.attacherVehicleCopy == nil then
        return
    end
    if type( self.attacherVehicleCopy.controlPanels ) == "table" then
        self.attacherVehicleCopy.isMouseActive = false
        local wasSuccessful = InteractiveControlPanel.removeControlPanel( self.attacherVehicleCopy, self);
    end;

    self.attacherVehicleCopy = nil;
    setVisibility( self.controlPanel, false )
end


function InteractiveControlPanel.addControlPanel( vehicle, object, position )    
    if object ~= nil then
        local controlPanelAttacher = nil;
        if position ~= nil and position < table.getn(vehicle.controlPanels) then
            if vehicle.controlPanels[position].loaded == nil then
                controlPanelAttacher = vehicle.controlPanels[position];
            end;
        else        
            for k,v in pairs(vehicle.controlPanels) do
                if v.loaded == nil then
                    controlPanelAttacher = v;
                    break;
                end;
            end;
        end;
        
        if controlPanelAttacher ~= nil and controlPanelAttacher.node ~= nil then
            -- link i3d-File
            unlink(object.controlPanel);
            link(controlPanelAttacher.node, object.controlPanel);
            controlPanelAttacher.loaded = object.controlPanel;
            controlPanelAttacher.implement = object;                    
            if object.interactiveObjects ~= nil then
                for _,interactiveObject in pairs(object.interactiveObjects) do                    
                    table.insert(vehicle.interactiveObjects, interactiveObject);
                end
                object.isControlingActive = true;
            end;
            return true;
        end;                
    end;
    
    return false;
end;

function InteractiveControlPanel.removeControlPanel( vehicle, object )
    if object ~= nil then
        for k,v in pairs(vehicle.controlPanels) do
            if v.implement == object then
                if v.loaded ~= nil and v.loaded == object.controlPanel then
                    -- unlink controlpanel
                    unlink(object.controlPanel);
                    link(object.detachPosition, object.controlPanel);
                end;
                v.loaded = nil;
                v.implement = nil;                
                
                if object.interactiveObjects ~= nil then
                    for l,w in pairs(vehicle.interactiveObjects) do
                        for _,interactiveObject in pairs(object.interactiveObjects) do                    
                            if w == interactiveObject then
                                table.remove(vehicle.interactiveObjects, l);
                                break;
                            end
                        end;
                    end;
                end;            
                object.isControlingActive = false;            
                
                return true;
            end;
        end;
    end;
    
    return false;
end;

function InteractiveControlPanel:getSaveAttributesAndNodes(nodeIdent)
  local nodes = ""
    
    for _,v in pairs(self.interactiveObjects) do
        if v.vehicle == self and v.saveAttributes then
            local str = v:getSaveAttributes()
            if str ~= nil and str ~= "" then
                if nodes ~= "" then
                    nodes = nodes .. "\n"
                end
                nodes = nodes .. nodeIdent .. "<interactiveComponent name=\"" .. v.id .. "\" ".. str .. " />"                    
            end
        end
    end
    
    return "", nodes
end

function InteractiveControlPanel:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
    local i=0
    while true do
        local xmlName = string.format(key..".interactiveComponent(%d)", i);    
        local id      = getXMLString(xmlFile, xmlName .. "#name")
        if id == nil then
            break
        end
        for _,v in pairs(self.interactiveObjects) do
            if v.id == id then
                if v.vehicle == self and v.saveAttributes then
                    local tmp = v.playSound
                    v.playSound = false
                    v:setSaveAttributes(xmlFile, xmlName)
                    v.playSound = tmp
                end
                break
            end
        end
        i = i + 1
    end

 return BaseMission.VEHICLE_LOAD_OK
end





InteractiveControlPanelEvent = {};
InteractiveControlPanelEvent_mt = Class(InteractiveControlPanelEvent, Event);

InitEventClass(InteractiveControlPanelEvent, "InteractiveControlPanelEvent");

function InteractiveControlPanelEvent:emptyNew()
    local self = Event:new(InteractiveControlPanelEvent_mt);
    return self;
end;

function InteractiveControlPanelEvent:new(vehicle, interactiveControlID)
    local self = InteractiveControlPanelEvent:emptyNew()
    self.vehicle = vehicle;
    self.interactiveControlID = interactiveControlID;
    return self;
end;

function InteractiveControlPanelEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.interactiveControlID = streamReadInt8(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function InteractiveControlPanelEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));    
    streamWriteInt8(streamId, self.interactiveControlID);
end;

function InteractiveControlPanelEvent:run(connection)
    self.vehicle.interactiveObjects[self.interactiveControlID]:doAction(true);    
    if not connection:getIsServer() then
        g_server:broadcastEvent(InteractiveControlPanelEvent:new(self.vehicle, self.interactiveControlID), nil, connection, self.vehicle);
    end;
end;

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

