package org.ntlab.radishforandroidstudio.cactusClient.models;

import net.arnx.jsonic.JSON;
import net.arnx.jsonic.TypeReference;

import org.ntlab.radishforandroidstudio.cactusClient.connections.ObjectsConnection;
import org.ntlab.radishforandroidstudio.framework.gameMain.GameBaseModel;
import org.ntlab.radishforandroidstudio.framework.gameMain.RealTime3DFragment;
import org.ntlab.radishforandroidstudio.framework.model3D.ModelFactory;
import org.ntlab.radishforandroidstudio.framework.model3D.Object3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Property3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Universe;
import org.ntlab.radishforandroidstudio.framework.network.CallBack;
import org.ntlab.radishforandroidstudio.java3d.Appearance;
import org.ntlab.radishforandroidstudio.java3d.Material;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * オブジェクトを管理するモデル
 */

public class MovableObjectModel implements GameBaseModel, CallBack {
    private Universe universe;
    private RealTime3DFragment fragment;
    private ObjectsConnection con;
    private String instanceId;
    private String objectId;
    private Map<String, Integer> visibleobject = new HashMap<>();

    public MovableObjectModel(RealTime3DFragment fragment, Universe universe) {
        this.fragment = fragment;
        this.universe = universe;
    }


    @Override
    public void setInstanceId(String id) {
        this.instanceId = id;
    }

    public void setObjectId(String objectId) {
        this.objectId = objectId;
    }

    /**
     * オブジェクトの状態更新
     *
     * @param interval 前回の更新からの時間差
     */
    @Override
    public void update(double interval) {
        con = new ObjectsConnection(instanceId);
        con.setCallBack(this);
        con.doGet();
    }


    @Override
    public void onResponse(String response) {

        Map<String, Integer> lastvisibleobject = new HashMap<>(visibleobject);
        visibleobject.clear();
        JSON json = new JSON();
        Map<String, Object> o = json.decode(response, new TypeReference<Map<String, Object>>() {
        });
        for (Map.Entry<String, Object> entry : o.entrySet()) {
            visibleobject.put(entry.getKey(), 1);
            ArrayList<Property3D> properties = new ArrayList<>();
            Object object = entry.getValue();

            // 自分自身は無視する
            System.out.println(entry.getKey() + ", " + objectId);
            if (entry.getKey().equals(objectId)) continue;

            properties.add(object.getPosition());
            properties.add(object.getAngle());

            if (!universe.doHaveObj(entry.getKey())){
                Appearance ap1 = new Appearance();
                Material mat = new Material();
                mat.setDiffuseColor(0.0f, 0.3f, 1.0f);
                mat.setAmbientColor(0.0f, 0.0f, 0.0f);
                mat.setEmissiveColor(0.0f, 0.0f, 0.0f);
                mat.setSpecularColor(0.0f, 0.0f, 0.0f);
                mat.setShininess(5.0f);
                ap1.setMaterial(mat);

                Object3D objBody = null;
                try {
                    objBody = ModelFactory.loadModel(fragment.getResources(),"cube-ascii.stl",ap1).createObject();
                }catch (Exception e){
                    e.printStackTrace();
                }

                MovableObject object1 =new MovableObject(objBody);
                universe.place(entry.getKey(),object1);
                universe.place(object1);

            }
            universe.apply(entry.getKey(),properties);
        }

        for (String key :lastvisibleobject.keySet()){
            if (visibleobject.get(key) == null){
                universe.displace(key);
            }
        }






    }
}
