--
-- Lanes
-- Specialization for Lanes
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @version 	v1.0
-- @date  		08/11/11
-- @history:	v1.0 - Initial version
--				v1.1 - Edit by JoXXer (BJR-Modding) to add functionality to run down grass
--

Lanes = {};

function Lanes.prerequisitesPresent(specializations)
    return true;
end;

function Lanes:load(xmlFile)
        self.lanesLimitToField = false;
        self.lanesForceLimitToField = true;
end;

function Lanes:delete()
end;

function Lanes:readStream(streamId, connection)
end;

function Lanes:writeStream(streamId, connection)
end;

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

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

function Lanes:update(dt)
end;

function Lanes:updateTick(dt)
    if self:getIsActive() then
        if self.isClient then
			for _,area in pairs(self.cuttingAreas) do
				if self:getIsAreaActive(area) then
					local x,y,z = getWorldTranslation(area.start);
					local x1,y1,z1 = getWorldTranslation(area.width);
					local x2,y2,z2 = getWorldTranslation(area.height);

					for index,fruit in pairs(g_currentMission.fruits) do
						--If it's any other fruit, run it down!
						local fruitDesc = FruitUtil.fruitIndexToDesc[index];
						if fruitDesc.needsSeeding then
							Utils.cutFruitArea(index, x, z, x1, z1, x2, z2);
							Utils.updateFruitCutShortArea(index, x, z, x1, z1, x2, z2, 0);
						end;
					end;
				end;
			end;
        end;
		--If it's grass, knock back to first growthState
		if self.isServer then
			local cuttingAreasSend = {};
			for k, cuttingArea in pairs(self.cuttingAreas) do
				if self:getIsAreaActive(cuttingArea) then
					local x,y,z = getWorldTranslation(cuttingArea.start);
					local x1,y1,z1 = getWorldTranslation(cuttingArea.width);
					local x2,y2,z2 = getWorldTranslation(cuttingArea.height);
					table.insert(cuttingAreasSend, {x,z,x1,z1,x2,z2});
				end;
			end;
			if table.getn(cuttingAreasSend) > 0 then
				local limitToField = self.lanesLimitToField or self.lanesForceLimitToField;
				if not g_currentMission.allowClientsCreateFields then
					local owner = self:getOwner();
					if owner ~= nil and not owner:getIsLocal() then
						limitToField = true;
					end;
				end;

				LanesEvent.runLocally(cuttingAreasSend, limitToField);
				g_server:broadcastEvent(LanesEvent:new(cuttingAreasSend, limitToField));
			end;
		end;
    end;
end;

function Lanes:draw()
end;

-- Lanes Event-class
LanesEvent = {};
LanesEvent_mt = Class(LanesEvent, Event);

InitEventClass(LanesEvent, "LanesEvent");

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

function LanesEvent:new(cuttingAreas, limitToField)
    local self = LanesEvent:emptyNew()
    assert(table.getn(cuttingAreas) > 0);
    self.cuttingAreas = cuttingAreas;
    self.limitToField = limitToField;
    return self;
end;

function LanesEvent:readStream(streamId, connection)
    local limitToField = streamReadBool(streamId);
    local numAreas = streamReadUIntN(streamId, 4);

    local refX = streamReadFloat32(streamId);
    local refY = streamReadFloat32(streamId);
    local values = Utils.readCompressed2DVectors(streamId, refX, refY, numAreas*3-1, 0.01, true);
    for i=1,numAreas do
        local vi = i-1;
		local x = values[vi*3+1].x;
        local z = values[vi*3+1].y;
        local x1 = values[vi*3+2].x;
        local z1 = values[vi*3+2].y;
        local x2 = values[vi*3+3].x;
        local z2 = values[vi*3+3].y;

		local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, x, z, x1, z1, x2, z2);
		setDensityMaskedParallelogram(g_currentMission.fruits[FruitUtil.FRUITTYPE_GRASS].id, x, z, widthX, widthZ, heightX, heightZ, 0, 3, g_currentMission.fruits[FruitUtil.FRUITTYPE_GRASS].id, 0, 3, 2.0);
    end;
end;


function LanesEvent:writeStream(streamId, connection)
    local numAreas = table.getn(self.cuttingAreas);
    streamWriteBool(streamId, self.limitToField);
    streamWriteUIntN(streamId, numAreas, 4);

    local refX, refY;
    local values = {};
    for i=1, numAreas do
        local d = self.cuttingAreas[i];
        if i==1 then
            refX = d[1];
            refY = d[2];
            streamWriteFloat32(streamId, d[1]);
            streamWriteFloat32(streamId, d[2]);
       else
            table.insert(values, {x=d[1], y=d[2]});
       end;
       table.insert(values, {x=d[3], y=d[4]});
        table.insert(values, {x=d[5], y=d[6]});
   end;
    assert(table.getn(values) == numAreas*3 - 1);
    Utils.writeCompressed2DVectors(streamId, refX, refY, values, 0.01);
end;

function LanesEvent:run(connection)
    print("Error: Do not run LanesEvent locally");
end;

function LanesEvent.runLocally(cuttingAreas, limitToField)

    local numAreas = table.getn(cuttingAreas);

    local refX, refY;
    local values = {};
    for i=1, numAreas do
        local d = cuttingAreas[i];
       if i==1 then
            refX = d[1];
           refY = d[2];
        else
            table.insert(values, {x=d[1], y=d[2]});
        end;
        table.insert(values, {x=d[3], y=d[4]});
        table.insert(values, {x=d[5], y=d[6]});
    end;
    assert(table.getn(values) == numAreas*3 - 1);

    local values = Utils.simWriteCompressed2DVectors(refX, refY, values, 0.01, true);

    for i=1, numAreas do
        local vi = i-1;
        local x = values[vi*3+1].x;
        local z = values[vi*3+1].y;
        local x1 = values[vi*3+2].x;
        local z1 = values[vi*3+2].y;
		local x2 = values[vi*3+3].x;
        local z2 = values[vi*3+3].y;

		local x,z, widthX,widthZ, heightX,heightZ = Utils.getXZWidthAndHeight(id, x, z, x1, z1, x2, z2);
		setDensityMaskedParallelogram(g_currentMission.fruits[FruitUtil.FRUITTYPE_GRASS].id, x, z, widthX, widthZ, heightX, heightZ, 0, 3, g_currentMission.fruits[FruitUtil.FRUITTYPE_GRASS].id, 0, 3, 2.0);
    end;
end;
