package com.geek_alarm.android.tasks; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; import java.util.Random; public final class TaskManager { private static final String SERVER_URL = "http://geekalarm-nbeloglazov.rhcloud.com/"; private static final Random RANDOM = new Random(); private static final HttpClient CLIENT = createClient(); private TaskManager() {} private static HttpClient createClient() { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(params, 30000); return new DefaultHttpClient(params); } private static HttpEntity sendRequest(String url) throws Exception { HttpUriRequest request = new HttpGet(SERVER_URL + url); HttpResponse response = CLIENT.execute(request); return response.getEntity(); } public static List<TaskType> getTaskTypes() throws Exception { String jsonText = EntityUtils.toString(sendRequest("tasks")); JSONArray array = new JSONArray(jsonText); List<TaskType> taskTypes = new ArrayList<TaskType>(); for (int i = 0; i < array.length(); i++) { taskTypes.add(jsonToTaskType(array.getJSONObject(i))); } return taskTypes; } private static TaskType jsonToTaskType(JSONObject json) throws JSONException { return new TaskType( json.getString("type"), json.getString("name"), json.getString("description"), TaskType.Level.MEDIUM); } private static Bitmap getImage(String url) throws Exception { HttpEntity entity = sendRequest(url); return BitmapFactory.decodeStream(entity.getContent()); } public static Task getTask(TaskType taskType) throws Exception { String url = String.format("task?type=%s&level=%d", taskType.getType(), taskType.getLevel().getValue()); HttpEntity taskEntity = sendRequest(url); JSONObject taskJson = new JSONObject(EntityUtils.toString(taskEntity)); String id = taskJson.getString("id"); Task task = new Task(); task.setId(id); task.setCorrect(Integer.parseInt(taskJson.getString("correct"))); task.setType(taskType); String questionUrl = String.format("image?id=%s&type=question", id); task.setQuestion(getImage(questionUrl)); for (int i = 0; i < 4; i++) { String choiceUrl = String.format( "image?id=%s&type=choice&number=%d", id, i); task.setChoice(i, getImage(choiceUrl)); } return task; } /** * Sends result of solving particular task to server for statistics. * @param id * @param isSolved */ public static void addResult(String id, boolean isSolved) throws Exception { if (id != null) { sendRequest(String.format("result?id=%s&solved=%s", id, isSolved)); } } private static Bitmap createBitmapWithText(String text) { float size = 30; Paint paint = new Paint(); paint.setTextSize(size); float width = paint.measureText(text); float height = paint.getTextSize(); Bitmap bitmap = Bitmap.createBitmap((int) width + 10, (int) height + 10, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); canvas.drawRGB(255, 255, 255); paint.setColor(Color.BLACK); canvas.drawText(text, 0, size, paint); return bitmap; } /** * Returns array of 4 elements. * 1 element is given number. * Others are random number close to given number. * @param number * @return */ private static int[] getSimilarNumbers(int number) { Random rand = new Random(); int[] res = new int[4]; res[0] = number; int unit = RANDOM.nextInt(2) * 2 - 1; int ten = (RANDOM.nextInt(2) * 2 - 1) * 10; res[1] = number + unit; res[2] = number + ten; res[3] = number + unit + ten; return res; } private static int shuffle(int[] numbers) { int pos = 0; for (int i = 0; i < 4; i++) { int a = RANDOM.nextInt(4); int b = RANDOM.nextInt(4); pos = a == pos ? b : (b == pos ? a : pos); int tmp = numbers[a]; numbers[a] = numbers[b]; numbers[b] = tmp; } return pos; } private static Task generateTaskByData(String question, int answer) { int[] choices = getSimilarNumbers(answer); int correct = shuffle(choices); Bitmap[] choicesBitMap = new Bitmap[4]; for (int i = 0; i < 4; i++) { String text = String.valueOf(choices[i]); choicesBitMap[i] = createBitmapWithText(text); } Task task = new Task(); task.setQuestion(createBitmapWithText(question)); task.setChoices(choicesBitMap); task.setCorrect(correct); task.setType(new TaskType(null, "Arithmetic", "Calculate value of given expression", null)); return task; } private static Task generateEasySimpleTask() { int a = RANDOM.nextInt(100); int b = RANDOM.nextInt(100); String question = String.format("%d + %d = ?", a, b); return generateTaskByData(question, a + b); } private static Task generateMediumSimpleTask() { int a = RANDOM.nextInt(100); int b = RANDOM.nextInt(100); String question = String.format("%d * %d = ?", a, b); return generateTaskByData(question, a * b); } private static Task generateHardSimpleTask() { int a = RANDOM.nextInt(100); int b = RANDOM.nextInt(100); int c = RANDOM.nextInt(100); String question = String.format("%1$d * %2$d + %3$d = ?", a, b, c); return generateTaskByData(question, a * b + c); } /** * When internet or server unavailable, * we create simple arithmetic tasks. * Like 12 * 23 + 33 = ? * @param difficulty * @return simple task. */ public static Task generateSimpleTask(int difficulty) { switch (difficulty) { case 1: return generateEasySimpleTask(); case 2: return generateMediumSimpleTask(); case 3: return generateHardSimpleTask(); } return null; } }