/*GR-SAKURA Sketch Template Version: V1.02*/
#include <rxduino.h>

/* GR-SAKURA mruby version                 */
/* 2013 copyright(c) NPO QUEST             */
/* AUTHOR 2013.2 N.Yamashita               */

#include "mruby.h"
#include "mruby/dump.h"
#include "mruby/proc.h"
#include "mruby/variable.h"
#include <stdint.h>

extern "C" {

	mrb_state *mrb;
	extern const char mrubylib[];

	void right(){
		digitalWrite(PIN_LED0, 1);
		digitalWrite(PIN_LED3, 0);
	}
	void left(){
		digitalWrite(PIN_LED0, 0);
		digitalWrite(PIN_LED3, 1);
	}
	void clear(){
		digitalWrite(PIN_LED0, 0);
		digitalWrite(PIN_LED3, 0);
	}
	void STOP (){
		while(1){
			digitalWrite(PIN_LED0, 1);
			digitalWrite(PIN_LED1, 1);
			digitalWrite(PIN_LED2, 1);
			digitalWrite(PIN_LED3, 1);
			delay(1000);
			digitalWrite(PIN_LED0, 0);
			digitalWrite(PIN_LED1, 0);
			digitalWrite(PIN_LED2, 0);
			digitalWrite(PIN_LED3, 0);
			delay(1000);
		}
	}
	void value(int x){
		digitalWrite(PIN_LED0,1);
		digitalWrite(PIN_LED1,1);
		digitalWrite(PIN_LED2,1);
		digitalWrite(PIN_LED3,1);
		delay(200);
		digitalWrite(PIN_LED0,0);
		digitalWrite(PIN_LED1,0);
		digitalWrite(PIN_LED2,0);
		digitalWrite(PIN_LED3,0);
		delay(200);
		digitalWrite(PIN_LED0,1);
		digitalWrite(PIN_LED1,1);
		digitalWrite(PIN_LED2,1);
		digitalWrite(PIN_LED3,1);
		delay(200);
		digitalWrite(PIN_LED0,0);
		digitalWrite(PIN_LED1,0);
		digitalWrite(PIN_LED2,0);
		digitalWrite(PIN_LED3,0);
		delay(200);
		int x2 = x / 256;
		digitalWrite(PIN_LED0,(x2>>3 & 0x01));
		digitalWrite(PIN_LED1,(x2>>2 & 0x01));
		digitalWrite(PIN_LED2,(x2>>1 & 0x01));
		digitalWrite(PIN_LED3,(x2>>0 & 0x01));
		delay(1000);
		digitalWrite(PIN_LED0,0);
		digitalWrite(PIN_LED1,0);
		digitalWrite(PIN_LED2,0);
		digitalWrite(PIN_LED3,0);
		delay(1000);
		int x1 = ((x - (x2 * 256 )))/16;
		digitalWrite(PIN_LED0,(x1>>3 & 0x01));
		digitalWrite(PIN_LED1,(x1>>2 & 0x01));
		digitalWrite(PIN_LED2,(x1>>1 & 0x01));
		digitalWrite(PIN_LED3,(x1>>0 & 0x01));
		delay(1000);
		digitalWrite(PIN_LED0,0);
		digitalWrite(PIN_LED1,0);
		digitalWrite(PIN_LED2,0);
		digitalWrite(PIN_LED3,0);
		delay(1000);
		int x0 = (x - (x2 * 256 ) - (x1 * 16));
		digitalWrite(PIN_LED0,(x0>>3 & 0x01));
		digitalWrite(PIN_LED1,(x0>>2 & 0x01));
		digitalWrite(PIN_LED2,(x0>>1 & 0x01));
		digitalWrite(PIN_LED3,(x0>>0 & 0x01));
		delay(1000);
		digitalWrite(PIN_LED0,0);
		digitalWrite(PIN_LED1,0);
		digitalWrite(PIN_LED2,0);
		digitalWrite(PIN_LED3,0);
		delay(1000);
	
	}
	void setup()
	{
		Serial.begin(9600,SCI_USB0);
		pinMode(PIN_LED0,OUTPUT);
		pinMode(PIN_LED1,OUTPUT);
		pinMode(PIN_LED2,OUTPUT);
		pinMode(PIN_LED3,OUTPUT);
		mrb = mrb_open();
	}
	void loop()
	{
//     Serial.println("Hello World!");
		

		int n = mrb_read_irep(mrb, mrubylib);
		if (n >= 0) {
			mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
		}
		mrb_close(mrb);
		
		STOP();

	}
	static mrb_value
	mrb_led_init(mrb_state *mrb, mrb_value self)
	{
		mrb_int number;
		mrb_int in_out;
	  mrb_get_args(mrb, "ii", &number, &in_out);
		if ((number < 0) || (number > 4)) {
			return mrb_nil_value();
		}
		if ((in_out < 0) || (in_out > 4))
		{
			return mrb_nil_value();
		}
		//ledิ๐i[
		mrb_iv_set(mrb, self, mrb_intern(mrb, "number"), mrb_fixnum_value(number));		pinMode((PIN_LED0 + number),in_out);
		return mrb_nil_value();
	}

	static mrb_value
	mrb_led(mrb_state *mrb, mrb_value self)
	{
		mrb_int pin;
		mrb_int on_off;
		mrb_value v;

		mrb_get_args(mrb, "i", &on_off);
		v = mrb_iv_get(mrb, self, mrb_intern(mrb, "number"));
		pin = mrb_fixnum(v);
		
		if ((pin < 0) || (pin > 3) || (on_off < 0) || (on_off > 1)){
			STOP();
		}
		digitalWrite((pin+PIN_LED0) , on_off);
		return mrb_nil_value();
	}

	static mrb_value
	mrb_delay(mrb_state *mrb, mrb_value self)
	{
		mrb_int interval;
		mrb_value v;
	  mrb_get_args(mrb, "i", &v);
		interval = mrb_fixnum(v);
		delay(interval);
		return mrb_nil_value();
	}

	static mrb_value
	mrb_gyaro_turn(mrb_state *mrb, mrb_value self)
	{
		mrb_int v;
		v = analogRead(1);
		if (v < 0x100) {
			return mrb_true_value();
		}else {
			return mrb_false_value();
		}
	}

	void
	mrb_init_userlib(mrb_state *mrb)
	{
	  struct RClass *led,*board,*gyaro;

	  led = mrb_define_class(mrb, "Led",mrb->object_class);
		mrb_define_method(mrb, led, "initialize", mrb_led_init,ARGS_REQ(2));
		mrb_define_method(mrb, led, "write",   mrb_led, ARGS_REQ(1));

		board = mrb_define_class(mrb, "Board",mrb->object_class);
		mrb_define_method(mrb, board, "delay",   mrb_delay, ARGS_REQ(1));

		gyaro = mrb_define_class(mrb, "Gyaro",mrb->object_class);
		mrb_define_method(mrb, gyaro, "turn?",   mrb_gyaro_turn, ARGS_NONE());

	}
}

