package com.ore.infinium.systems;

import com.badlogic.ashley.core.*;
import com.badlogic.ashley.utils.ImmutableArray;
import com.badlogic.gdx.math.Vector2;
import com.ore.infinium.LoadedViewport;
import com.ore.infinium.Mappers;
import com.ore.infinium.World;
import com.ore.infinium.components.PlayerComponent;
import com.ore.infinium.components.SpriteComponent;

/**
 * ***************************************************************************
 * Copyright (C) 2015 by Shaun Reich <sreich@kde.org>                    *
 * *
 * This program is free software; you can redistribute it and/or            *
 * modify it under the terms of the GNU General Public License as           *
 * published by the Free Software Foundation; either version 2 of           *
 * the License, or (at your option) any later version.                      *
 * *
 * This program is distributed in the hope that it will be useful,          *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 * GNU General Public License for more details.                             *
 * *
 * You should have received a copy of the GNU General Public License        *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
 * ***************************************************************************
 */
public class PlayerSystem extends EntitySystem implements EntityListener {
    private World m_world;

    public PlayerSystem(World world) {
        m_world = world;
    }

    public void addedToEngine(Engine engine) {
        engine.addEntityListener(Family.all(PlayerComponent.class).get(), this);
    }

    public void removedFromEngine(Engine engine) {

    }

    public void update(float delta) {
        if (m_world.isClient()) {
            return;
        }

        ImmutableArray<Entity> entities = m_world.engine.getEntitiesFor(Family.all(PlayerComponent.class).get());

        //clients, for now, do their own collision stuff. mostly.
        //FIXME: clients should simulate their own player's collision with everything and tell the server its position so it can broadcast.
        // but nothing else.
        //server will simulate everything else(except players), and broadcast positions
        for (Entity e : entities) {
            SpriteComponent spriteComponent = Mappers.sprite.get(e);
            PlayerComponent playerComponent = Mappers.player.get(e);

            if (Vector2.dst(spriteComponent.sprite.getX(), spriteComponent.sprite.getY(), playerComponent.lastLoadedRegion.x, playerComponent.lastLoadedRegion.y)
                    > 20.0f) {
                //HACK, dunno why 20. need something sane.
                calculateLoadedViewport(e);
            }
        }
    }

    private void calculateLoadedViewport(Entity entity) {
        PlayerComponent playerComponent = Mappers.player.get(entity);
        SpriteComponent spriteComponent = Mappers.sprite.get(entity);


        LoadedViewport loadedViewport = playerComponent.loadedViewport;

        Vector2 center = new Vector2(spriteComponent.sprite.getX(), spriteComponent.sprite.getY());
        loadedViewport.centerOn(center);
        playerComponent.lastLoadedRegion = center;

        m_world.m_server.sendPlayerLoadedViewportMoved(entity);
    }

    @Override
    public void entityAdded(Entity entity) {
        if (m_world.isClient()) {
            return;
        }

        //initial spawn, send region
        calculateLoadedViewport(entity);

        PlayerComponent playerComponent = Mappers.player.get(entity);
        LoadedViewport loadedViewport = playerComponent.loadedViewport;

        int x = (int) (Math.max(0.0f, loadedViewport.rect.x - loadedViewport.rect.width) / World.BLOCK_SIZE);
        int y = (int) (Math.max(0.0f, loadedViewport.rect.y - loadedViewport.rect.height) / World.BLOCK_SIZE);
        int x2 = (int) (Math.min(World.BLOCK_SIZE * World.WORLD_COLUMNCOUNT, loadedViewport.rect.x + loadedViewport.rect.width) / World.BLOCK_SIZE);
        int y2 = (int) (Math.min(World.BLOCK_SIZE * World.WORLD_ROWCOUNT, loadedViewport.rect.y + loadedViewport.rect.height) / World.BLOCK_SIZE);

        m_world.m_server.sendPlayerBlockRegion(entity, x, y, x2, y2);
    }

    @Override
    public void entityRemoved(Entity entity) {

    }
}

@@ -2663,17 +2663,17 @@
       %3E 
-2
+1
 0.0f) %7B%0A
@@ -3344,213 +3344,105 @@
     
-%7D%0A%0A
     
-@Override%0A    public void entityAdded(Entity entity) %7B%0A        if (m_world.isClient()) %7B%0A            return;%0A        %7D%0A%0A        //initial spawn, send region%0A        calculateLoadedViewport(
+sendPlayerBlockRegion(entity);%0A    %7D%0A%0A    private void sendPlayerBlockRegion(Entity 
 entity)
-;%0A
+ %7B
 %0A   
@@ -4172,24 +4172,272 @@
 y2);%0A    %7D%0A%0A
+    @Override%0A    public void entityAdded(Entity entity) %7B%0A        if (m_world.isClient()) %7B%0A            return;%0A        %7D%0A%0A        //initial spawn, send region%0A        calculateLoadedViewport(entity);%0A        sendPlayerBlockRegion(entity);%0A    %7D%0A%0A
     @Overrid

fix periodic loaded region sending