OrkanAreaEvent = {};
OrkanAreaEvent_mt = Class(OrkanAreaEvent, Event);

InitEventClass(OrkanAreaEvent, "OrkanAreaEvent");

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

function OrkanAreaEvent:new(cuttingAreas, fruitType)
    local self = OrkanAreaEvent:emptyNew()
    self.cuttingAreas = cuttingAreas;
    self.fruitType = fruitType;
    return self;
end;

function OrkanAreaEvent:readStream(streamId, connection)
    local fruitType = streamReadInt8(streamId);
    local _fruitType = FruitUtil.fillTypeToFruitType[fruitType];
    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;
		Utils.updateFruitCutShortArea(_fruitType, x, z, x1, z1, x2, z2, 1);	
		Utils.cutFruitArea(_fruitType, x, z, x1, z1, x2, z2);
		Utils.updateFruitWindrowArea(_fruitType, x, z, x1, z1, x2, z2, 0);
		Utils.updateFruitCutLongArea(_fruitType, x, z, x1, z1, x2, z2, 0);
    end;
end;

function OrkanAreaEvent:writeStream(streamId, connection)
    streamWriteInt8(streamId,self.fruitType);
    local numAreas = table.getn(self.cuttingAreas);
    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 OrkanAreaEvent:run(connection)
    print("Error: Do not run OrkanAreaEvent locally");
end;

function OrkanAreaEvent.runLocally(cuttingAreas, fillTypes, currentFillType)
    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);
    local area = 0;
    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;
		for fruitType,v in pairs(fillTypes) do
			if fruitType ~= Fillable.FILLTYPE_UNKNOWN then
				if currentFillType == fruitType or currentFillType == Fillable.FILLTYPE_UNKNOWN then
					local _fruitType = FruitUtil.fillTypeToFruitType[fruitType];
					Utils.updateFruitCutShortArea(_fruitType, x, z, x1, z1, x2, z2, 1);
					local area = Utils.cutFruitArea(_fruitType, x, z, x1, z1, x2, z2);
					area = area + Utils.updateFruitWindrowArea(_fruitType, x, z, x1, z1, x2, z2, 0)*g_currentMission.windrowCutLongRatio;
					area = area + Utils.updateFruitCutLongArea(_fruitType, x, z, x1, z1, x2, z2, 0);
					if area > 0 then
						return area, fruitType;
					end;						
				end;
			end;
		end;
    end;
    return area, fruitType;
end;