/*
 * Samsung API
 * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "main.h"
#include "log.h"

void mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	appdata_s *ad = data;
	Evas_Object *piece = obj;
	int r, g, b, a;

	if(evas_object_data_get(piece, "position") == evas_object_data_get(ad->piece[ad->white_piece], "position")) {
		return;
	}

	evas_object_color_get(piece, &r, &g, &b, &a);
	evas_object_color_set(piece, r, g, b, 200);

	evas_object_show(piece);
}

void mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	appdata_s *ad = data;
	Evas_Object *piece = obj;
	int size;
	int position;
	int white_piece;

	position = (int)evas_object_data_get(piece, "position");
	white_piece = ad->white_piece;
	size = ad->size;

	if(position == (int)evas_object_data_get(ad->piece[white_piece], "position")) {
		return;
	}

	evas_object_color_set(piece, 255, 255, 255, 255);

	if(position-size == white_piece) {
		if(move_puzzle_to_up(ad) < 0) {
			_E("Fail move piece");
		}
	} else if(position-1 == white_piece && ((white_piece+1)%size)) {
		if(move_puzzle_to_left(ad) < 0) {
			_E("Fail move piece");
		}
	} else if(position+1 == white_piece && (white_piece%size)) {
		if(move_puzzle_to_right(ad) < 0) {
			_E("Fail move piece");
		}
	} else if(position+size == white_piece) {
		if(move_puzzle_to_down(ad) < 0) {
			_E("Fail move piece");
		}
	}

	evas_object_show(piece);
}


int move_puzzle_to_down(void *data)
{
	_D("Move puzzle Down");
	retv_if(!data, 0);

	appdata_s *ad = data;
	int x1, y1, w1, h1;
	int x2, y2, w2, h2;
	int white_piece;
	int size;
	int temp;

	white_piece = ad->white_piece;
	size = ad->size;

	if(white_piece-size < 0) {
		return SAMPLE_APP_ERROR_OK;
	}

	evas_object_image_load_region_get(ad->piece[white_piece - size], &x1, &y1, &w1, &h1);
	evas_object_image_load_region_get(ad->piece[white_piece], &x2, &y2, &w2, &h2);

	evas_object_image_load_region_set(ad->piece[white_piece - size], x2, y2, w2, h2);
	evas_object_image_load_region_set(ad->piece[white_piece], x1, y1, w1, h1);

	evas_object_color_set(ad->piece[white_piece], ad->r, ad->g, ad->b, ad->a);
	evas_object_color_set(ad->piece[white_piece - size], ad->r, ad->g, ad->b, 0);

	evas_object_show(ad->piece[white_piece]);
	evas_object_show(ad->piece[white_piece - size]);

	temp = ad->piece_pos[white_piece];
	ad->piece_pos[white_piece] = ad->piece_pos[white_piece - size];
	ad->piece_pos[white_piece - size] = temp;

	ad->white_piece = white_piece - size;

	if(ad->piece_pos[ad->white_piece] == size*size-1 && ad->start == 1) {
		puzzle_correct_cb(ad);
	}

	return 1;
}

void move_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	if (!move_puzzle_to_down(data)) {
		_D("Cannot move to down");
	}
}

int move_puzzle_to_up(void *data)
{
	_D("Move puzzle UP");
	retv_if(!data, 0);

	appdata_s *ad = data;
	int x1, y1, w1, h1;
	int x2, y2, w2, h2;
	int white_piece = ad->white_piece;
	int size = ad->size;
	int temp;

	if(white_piece+size >= size*size) {
		_D("Reached end");
		return SAMPLE_APP_ERROR_OK;
	}

	evas_object_image_load_region_get(ad->piece[white_piece + size], &x1, &y1, &w1, &h1);
	evas_object_image_load_region_get(ad->piece[white_piece], &x2, &y2, &w2, &h2);

	evas_object_image_load_region_set(ad->piece[white_piece + size], x2, y2, w2, h2);
	evas_object_image_load_region_set(ad->piece[white_piece], x1, y1, w1, h1);

	evas_object_color_set(ad->piece[white_piece], ad->r, ad->g, ad->b, ad->a);
	evas_object_color_set(ad->piece[white_piece + size], ad->r, ad->g, ad->b, 0);

	evas_object_show(ad->piece[white_piece]);
	evas_object_show(ad->piece[white_piece + size]);

	temp = ad->piece_pos[white_piece];
	ad->piece_pos[white_piece] = ad->piece_pos[white_piece + size];
	ad->piece_pos[white_piece + size] = temp;

	ad->white_piece = white_piece + size;

	if(ad->piece_pos[ad->white_piece] == size*size-1 && ad->start == 1) {
		_D("Is it correct?");
		puzzle_correct_cb(ad);
	}

	return 1;
}

void move_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	if (!move_puzzle_to_up(data)) {
		_D("Cannot move to up");
	}
}

int move_puzzle_to_right(void *data)
{
	_D("Move puzzle Right");
	retv_if(!data, 0);

	appdata_s *ad = data;
	int x1, y1, w1, h1;
	int x2, y2, w2, h2;
	int white_piece = ad->white_piece;
	int size = ad->size;
	int temp;

	if(!(white_piece%size)) {
		return SAMPLE_APP_ERROR_OK;
	}

	evas_object_image_load_region_get(ad->piece[white_piece -1], &x1, &y1, &w1, &h1);
	evas_object_image_load_region_get(ad->piece[white_piece], &x2, &y2, &w2, &h2);

	evas_object_image_load_region_set(ad->piece[white_piece - 1], x2, y2, w2, h2);
	evas_object_image_load_region_set(ad->piece[white_piece], x1, y1, w1, h1);

	evas_object_color_set(ad->piece[white_piece], ad->r, ad->g, ad->b, ad->a);
	evas_object_color_set(ad->piece[white_piece - 1], ad->r, ad->g, ad->b, 0);

	evas_object_show(ad->piece[white_piece]);
	evas_object_show(ad->piece[white_piece - 1]);

	temp = ad->piece_pos[white_piece];
	ad->piece_pos[white_piece] = ad->piece_pos[white_piece - 1];
	ad->piece_pos[white_piece - 1] = temp;

	ad->white_piece = white_piece - 1;

	if(ad->piece_pos[ad->white_piece] == size*size-1 && ad->start == 1) {
		puzzle_correct_cb(ad);
	}

	return 1;
}

void move_right_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	if (!move_puzzle_to_right(data)) {
		_D("Cannot move to right");
	}
}

int move_puzzle_to_left(void *data)
{
	_D("Move puzzle Left");
	retv_if(!data, 0);

	appdata_s *ad = data;
	int x1, y1, w1, h1;
	int x2, y2, w2, h2;
	int white_piece = ad->white_piece;
	int size = ad->size;
	int temp;

	if(!((white_piece+1)%size)) {
		return SAMPLE_APP_ERROR_OK;
	}

	evas_object_image_load_region_get(ad->piece[white_piece + 1], &x1, &y1, &w1, &h1);
	evas_object_image_load_region_get(ad->piece[white_piece], &x2, &y2, &w2, &h2);

	evas_object_image_load_region_set(ad->piece[white_piece + 1], x2, y2, w2, h2);
	evas_object_image_load_region_set(ad->piece[white_piece], x1, y1, w1, h1);

	evas_object_color_set(ad->piece[white_piece], ad->r, ad->g, ad->b, ad->a);
	evas_object_color_set(ad->piece[white_piece + 1], ad->r, ad->g, ad->b, 0);

	evas_object_show(ad->piece[white_piece]);
	evas_object_show(ad->piece[white_piece + 1]);

	temp = ad->piece_pos[white_piece];
	ad->piece_pos[white_piece] = ad->piece_pos[white_piece + 1];
	ad->piece_pos[white_piece + 1] = temp;

	ad->white_piece = white_piece + 1;

	if(ad->piece_pos[ad->white_piece] == size*size-1 && ad->start == 1) {
		puzzle_correct_cb(ad);
	}

	return 1;
}

void move_left_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	ret_if(!data);

	if (!move_puzzle_to_left(data)) {
		_D("Cannot move to left");
	};
}

Eina_Bool _shuffle_cb(appdata_s *ad)
{
	ad->shuffle_count++;
	int func = rand( )% 4;
	int ret;

	if(func == 0) {
		if(!(ret = move_puzzle_to_up(ad))) {
			ad->shuffle_count--;
			if(ret<0) {
				_E("Fail move piece");
			}
		}
	} else if (func == 1) {
		if(!(ret = move_puzzle_to_down(ad))) {
			ad->shuffle_count--;
			if(ret < 0) {
				_E("Fail move piece");
			}
		}
	} else if(func == 2) {
		if(!(ret=move_puzzle_to_left(ad))) {
			ad->shuffle_count--;
			if(ret<0) {
				_E("Fail move piece");
			}
		}
	} else if(func == 3) {
		if(!(ret=move_puzzle_to_right(ad))) {
			ad->shuffle_count--;
			if(ret<0) {
				_E("Fail move piece");
			}
		}
	}
	if (ad->shuffle_count < 70) {
		return ECORE_CALLBACK_RENEW;
	} else {
		ad->shuffling = 0;
		return ECORE_CALLBACK_CANCEL;
	}
}

void move_shuffle_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
	_D("Everybody Shuffle Dance");
	ret_if(!data);
	Ecore_Animator *animator;
	appdata_s *ad = data;

	if (ad->shuffling == 1) {
		_D("Puzzle is in Shuffling");
		return;
	}

	ad->shuffle_count = 0;
	ad->shuffling = 1;

	//ecore_timer_add(0.03f, _shuffle_cb, ad);
	animator = ecore_animator_add(_shuffle_cb, ad);
}

Evas_Object *dir_btn_create(appdata_s *ad, Evas_Object *layout)
{
	_D(" dir btn create");
	retv_if(!ad, NULL);
	retv_if(!layout, NULL);

	Evas_Object *dir_btn = NULL;
	Evas_Object *up_btn = NULL;
	Evas_Object *down_btn = NULL;
	Evas_Object *left_btn = NULL;
	Evas_Object *right_btn = NULL;

	dir_btn = elm_layout_add(ad->win);
	retv_if(!dir_btn, NULL);
	evas_object_size_hint_weight_set(dir_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	elm_layout_file_set(dir_btn, ad->puzzle_edj_path, GRP_DIR_BTN);

	up_btn = elm_button_add(dir_btn);
	retv_if(!up_btn, NULL);
	elm_object_part_text_set(up_btn, NULL, "UP");
	elm_object_part_content_set(dir_btn, "up_button", up_btn);
	evas_object_event_callback_add(up_btn, EVAS_CALLBACK_MOUSE_UP, move_up_cb, ad);

	down_btn = elm_button_add(dir_btn);
	retv_if(!down_btn, NULL);
	elm_object_part_text_set(down_btn, NULL, "DOWN");
	elm_object_part_content_set(dir_btn, "down_button", down_btn);
	evas_object_event_callback_add(down_btn, EVAS_CALLBACK_MOUSE_UP, move_down_cb, ad);

	left_btn = elm_button_add(dir_btn);
	retv_if(!left_btn, NULL);
	elm_object_part_text_set(left_btn, NULL, "LEFT");
	elm_object_part_content_set(dir_btn, "left_button", left_btn);
	evas_object_event_callback_add(left_btn, EVAS_CALLBACK_MOUSE_UP, move_left_cb, ad);

	right_btn = elm_button_add(dir_btn);
	retv_if(!right_btn, NULL);
	elm_object_part_text_set(right_btn, NULL, "RIGHT");
	elm_object_part_content_set(dir_btn, "right_button", right_btn);
	evas_object_event_callback_add(right_btn, EVAS_CALLBACK_MOUSE_UP, move_right_cb, ad);

	elm_object_part_content_set(layout, "dir_btn", dir_btn);

	return dir_btn;
}
