package controllers;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.hash.Hashing;
import play.cache.Cache;
import play.data.DynamicForm;
import play.data.Form;
import play.libs.F;
import play.libs.ws.WS;
import play.libs.ws.WSResponse;
import play.mvc.Controller;
import play.mvc.Result;
import util.ChessUtils;
import views.html.about;
import views.html.index;
import views.html.result;

import java.util.concurrent.Callable;

import static play.libs.F.Promise.promise;

public class Application extends Controller {

  public Result index() {
    Form form = Form.form();
    return ok(index.render(form));
  }

  public Result about() {
    return ok(about.render());
  }

  public Result result(String key) {
    if (Cache.get(key) == null) {
      return notFound();
    }
    return ok(result.render(key));
  }

  public F.Promise<Result> gif(String key) {
    F.Promise<byte[]> result = (F.Promise<byte[]>) Cache.get(key);
    if (result != null) {
      return result.map(r -> ok(r).as("image/gif"));
    }

    return promise(() -> notFound());
  }

  public F.Promise<Result> download(String key) {
    F.Promise<byte[]> result = (F.Promise<byte[]>) Cache.get(key);
    if (result != null) {
      response().setHeader("Content-Disposition", "attachement");
      response().setHeader("filename", "chess-gif.gif");
      return result.map(r -> ok(r).as("image/gif"));
    }

    return promise(() -> notFound());
  }

  public F.Promise<Result> gfyfy(String key) {
    String url = "http://upload.gfycat.com/transcode?fetchUrl=" + routes.Application.gif(key).absoluteURL(request());
    F.Promise<WSResponse> responsePromise = WS.url(url).get();
    return responsePromise.map(r -> {
      JsonNode gfyName = r.asJson().get("gfyName");
      return gfyName.textValue();
    })
      .map(name -> temporaryRedirect("http://gfycat.com/" + name));
  }

  public F.Promise<Result> pgn() {
    DynamicForm requestData = Form.form().bindFromRequest();
    String pgn = requestData.get("pgn");
    String color = requestData.get("color");

    String sizeParam = requestData.get("size");
    int size = sizeParam != null ? Integer.valueOf(sizeParam) : 400;

    int moveDelay = requestData.get("delay") == null ? 800 : (int) (Float.parseFloat(requestData.get("delay")) * 1000);
    int lastDelay = requestData.get("lastDelay") == null ? 800 : (int) (Float.parseFloat(requestData.get("lastDelay")) * 1000);

    String key = Hashing.murmur3_32().hashUnencodedChars(pgn + "-" + color + "-" + size + "-" + moveDelay + "-" + lastDelay).toString();

    F.Promise<byte[]> result = Cache.getOrElse(key, new Callable<F.Promise<byte[]>>() {
      @Override public F.Promise<byte[]> call() throws Exception {
        return promise(() -> ChessUtils.gif(pgn, color, size, moveDelay, lastDelay));
      }
    }, 0);

    return result.map((r) -> temporaryRedirect(controllers.routes.Application.result(key)));
  }
}

@@ -537,16 +537,192 @@
 roller %7B
+%0A  %0A  private static final int DEFAULT_BOARD_SIZE_PX = 320;%0A  private static final int DEFAULT_MOVE_DELAY_MS = 800;%0A  private static final int DEFAULT_LAST_MOVE_DELAY_MS = 800;
 %0A%0A  publ
@@ -2355,11 +2355,29 @@
 ) : 
-400
+DEFAULT_BOARD_SIZE_PX
 ;%0A%0A 
@@ -2422,35 +2422,53 @@
 lay%22) == null ? 
-800
+DEFAULT_MOVE_DELAY_MS
  : (int) (Float.
@@ -2572,19 +2572,42 @@
  null ? 
-800
+DEFAULT_LAST_MOVE_DELAY_MS
  : (int)

Refactor constants into static fields