/*
 * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
 */
package kr.co.zumo.app.lifeplus.view.presenter;

import android.util.Log;

import com.google.gson.Gson;

import kr.co.zumo.app.lifeplus.model.Model;
import kr.co.zumo.app.lifeplus.network.INetworkReceiverListener;
import kr.co.zumo.app.lifeplus.supervisor.ScreenID;
import kr.co.zumo.app.lifeplus.view.Event;
import kr.co.zumo.app.lifeplus.view.IView;
import kr.co.zumo.app.lifeplus.view.command.ActivityChangeCommand;
import kr.co.zumo.app.lifeplus.view.command.Command;

/**
 * Presenter
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018. 9. 21.]   [최초 작성]
 * @since 2018. 9. 21.
 */
public abstract class Presenter<M extends Model, V extends IView> implements INetworkReceiverListener {

  protected M model;
  protected V view;
  protected Command command;

  public Presenter(M model, V view) {
    this.model = model;
    this.view = view;
  }

  /**
   * dispose
   */
  public final void dispose() {
    model.dispose();

    onDispose();
  }

  /***********************************
   * abstract
   ***********************************/
  /**
   * start
   */
  public abstract void start();

  protected abstract void onDispose();

  /**
   * 장치 back key 눌렸을 경우 처리한다.
   * - 이벤트를 처리했다면 true 를 반환한다.
   * - false 를 반환하면 activity 에서 기본값으로 처리된다.
   *
   * @return boolean true = consumed
   */
  public abstract boolean onBackPressed();

  /**
   * View 로 부터 전달된 이벤트를 처리한다.
   * - 공통 처리가 필요한 이벤트를 처리한 뒤
   * - 각 Presenter.performOnEvent(Event) 에서 세부 처리한다.
   *
   * @param event
   */
  public void onEvent(Event event) {
    performOnEvent(event);
  }

  protected abstract void performOnEvent(Event event);

  /***********************************
   * method
   ***********************************/
  void onCommand(Command command) {
    this.command = command;
    Log.w("APP# Presenter | onCommand", "| command: " + command.getClass().getSimpleName() + ", " + new Gson().toJson(command));
    command.preExecute(model, view, this);
    command.execute(model, view, this);
    command.postExecute(model, view, this);
  }

  /***********************************
   * listener
   ***********************************/
  @Override
  public void onChangedConnection(boolean isConnected, int type) {
    Log.i("APP# Presenter | onChangedConnection", "| " + this.getClass().getSimpleName() + ", isConnected:" + isConnected);

    if (false == isConnected) {
      onCommand(new ActivityChangeCommand(ScreenID.ACTIVITY_NETWORK_ERROR, ScreenID.DIRECTION_BACK));
    }
  }
}
