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

import android.support.annotation.IntDef;

import com.google.gson.Gson;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * View 에서 Presenter 로 전달할 이벤트 객체
 * - Event.Builder 를 통해서만 생성이 가능하다.
 * - Dialog 이벤트에도 이용된다.
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018. 9. 5.]   [최초 작성]
 * @since 2018. 9. 5.
 */
public class Event {

  /***********************************
   * Constants
   ***********************************/

  // main event
  public static final int NONE = -1;
  public static final int CLICK = 0;
  public static final int BACK = 1;
  public static final int SIGN_UP = 2;
  public static final int LOGIN = 3;
  public static final int CHECK = 4;
  public static final int UNCHECK = 5;
  public static final int JOINED = 7;
  public static final int TUTORIAL_LEFT = 11;
  public static final int TUTORIAL_RIGHT = 12;
  public static final int RETRY = 13;
  public static final int INPUT_PIN = 14;
  public static final int NETWORK_CONNECTED = 15;
  public final static int SUCCESS = 16;
  public final static int FAIL = 17;
  public final static int CANCEL = 18;
  public final static int EMAIL_CLICK = 19;
  public final static int SPECIAL_CODE_CLICK = 20;
  public static final int CONFIRM = 21;
  public static final int RESULT = 22;
  public static final int CHANGED = 23;
  public static final int INIT = 24;
  public static final int DETAIL = 25;
  public static final int ERROR = 26;
  public static final int UNLOCK = 27;
  public static final int RESET = 28;
  public static final int FAQ = 29;
  public static final int DELETE = 30;
  public static final int COMPLETED = 31;
  public static final int TUTORIAL_END = 33;
  public static final int EXIT = 34;
  public static final int START = 35;

  @Retention(RetentionPolicy.SOURCE)
  @IntDef({
    NONE, CLICK, BACK, SIGN_UP, LOGIN, CHECK, UNCHECK, JOINED, TUTORIAL_LEFT, TUTORIAL_RIGHT,
    RETRY, INPUT_PIN, NETWORK_CONNECTED, CHANGED, INIT, DETAIL, ERROR, UNLOCK, RESET,
    SUCCESS, FAIL, CANCEL, EMAIL_CLICK, SPECIAL_CODE_CLICK, CONFIRM, RESULT, FAQ, DELETE,
    COMPLETED, TUTORIAL_END, EXIT, START,
  })
  public @interface ID {}

  // sub event
  public static final int BANNER_REQUEST = 1000;
  public static final int POLICY_REQUEST = 1001;
  public static final int POLICY_CONFIRM = 1002;
  public static final int MEMBER_JOIN = 1003;
  public static final int MEMBER_DELETE = 1004;
  public static final int MEMBER_LOGIN = 1005;

  /***********************************
   * Object
   ***********************************/
  private final int eventId;
  private final int integer;
  private final String string;
  private final String json;

  private Event(@Event.ID int eventId, int integer, String string, String json) {
    this.eventId = eventId;
    this.integer = integer;
    this.string = string;
    this.json = json;
  }

  /**
   * event id
   *
   * @return Event.ID
   */
  public int getEventId() {
    return eventId;
  }

  /**
   * int value
   *
   * @return int
   */
  public int getInteger() {
    return integer;
  }

  /**
   * string value
   *
   * @return string
   */
  public String getString() {
    return string;
  }

  /**
   * json value
   *
   * @return string of json
   */
  public String getJson() {
    return json;
  }

  /**
   * 저장된 json string 을 지정한 클래스로 변환
   *
   * @param beanClass class of Bean
   * @param <T>
   * @return converted Bean from json string
   */
  public <T> T fromJson(Class<T> beanClass) {
    return new Gson().fromJson(json, beanClass);
  }


  /***********************************
   * Builder
   ***********************************/
  /**
   * Event 객체를 생성하기 위한 builder
   */
  public static class Builder {
    private int eventId;
    private int integer = NONE;
    private String string = null;
    private String json = null;

    /**
     * 필수 항목인 eventId 를 전달 받는다.
     *
     * @param eventId Event.ID
     */
    public Builder(@Event.ID int eventId) {
      this.eventId = eventId;
    }

    /**
     * int value 설정
     *
     * @param value int
     * @return Builder
     */
    public Builder integer(int value) {
      this.integer = value;
      return this;
    }

    /**
     * string value 설정
     *
     * @param value string
     * @return Builder
     */
    public Builder string(String value) {
      this.string = value;
      return this;
    }

    /**
     * json value 설정
     *
     * @param value string of json
     * @return Builder
     */
    public Builder json(String value) {
      this.json = value;
      return this;
    }

    /**
     * Event 객체 반환
     *
     * @return Event
     */
    public Event build() {
      return new Event(eventId, integer, string, json);
    }
  }
}
