﻿/* Common Functions */

function log(obj){
	window.console.log(obj);
}

var Event = Object();
Event.observe = function(obj, mode, handler){
	try {
		obj.addEventListener(mode, handler, false);
	}catch(e) {
		try {
			obj.attachEvent('on'+mode, handler, false);
		}catch(e) {}
	}
}
Event.pointer = function(event) {
	  var docElement = document.documentElement,
	  body = document.body || { scrollLeft: 0, scrollTop: 0 };
	  return {
		x: event.pageX || (event.clientX +
		  (docElement.scrollLeft || body.scrollLeft) -
		  (docElement.clientLeft || 0)),
		y: event.pageY || (event.clientY +
		  (docElement.scrollTop || body.scrollTop) -
		  (docElement.clientTop || 0))
	  };
}
Event.pointerX = function(event) { return Event.pointer(event).x }
Event.pointerY = function(event) { return Event.pointer(event).y }


var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
  	}
}

Object.extend = function(destination, source) {
	for (var property in source) {
		destination[property] = source[property];
	}
	return destination;
}

Function.prototype.binds = function() {
	var __method = this, args = $A(arguments), object = args.shift();
	return function() {
		return __method.apply(object, args.concat($A(arguments)));
	}
}

var $A = Array.from = function(iterable) {
	if (!iterable) return [];
	if (iterable.toArray) {
		return iterable.toArray();
	} else {
	var results = [];
	for (var i = 0; i < iterable.length; i++)
		results.push(iterable[i]);
		return results;
	}
}

function lateFunc(func){
		setTimeout(function(){
			try{
				func()
			}catch(e){
				setTimeout(arguments.callee, 100);
			}
		}, 100);
}

function track(url){
	try {
		pageTracker._trackPageview(url);
	}catch(e){}
	log(url);
}

/* Canvas Class */
 var Canvas = Class.create();
Canvas.prototype = {
	initialize: function(canvas, num){
		this.canvas   = canvas;
		this.context = this.canvas.getContext('2d');
		this.x	   = this.canvas.offsetLeft;
		this.y	   = this.canvas.offsetTop;
		this.context.lineCap = 'round';
		this.context.lineJoin = 'round';
		this.setStroke();
		this.f_draw  = false; // Draw flag
		this.cache   = this.moveEvent.binds(this);
		this.history = new History(this.canvas, this.context);

		Event.observe(this.canvas, 'mousedown', this.begin.binds(this));
		Event.observe(this.canvas, 'mouseup',   this.end.binds(this));
		Event.observe(this.canvas, 'touchstart', this.begin.binds(this));
		Event.observe(this.canvas, 'touchend',   this.end.binds(this));
		//Event.observe(window, 'mouseup',   this.end.binds(this));
		//Event.observe(this.canvas, 'mouseout',  this.end.bind(this));
		$('#color').change(this.setStroke.binds(this));
		$('#width').change(this.setStroke.binds(this));
		//$('#opacity').change(this.setStroke.binds(this));
	},
	setStroke: function(){
		this.context.strokeStyle = $('#color').val();
		this.context.lineWidth = $('#width').val();
		this.context.globalAlpha = 1;
		//this.context.globalAlpha = $('#opacity').val();
	},
	// Start draw
	begin: function(e){
		//if(this.check2Touch(e)) return;

		if(this.history.count()>=140) return;

		e.preventDefault();
		
		this.f_draw = true;
		Event.observe(this.canvas, 'mousemove', this.cache);
		Event.observe(this.canvas, 'touchmove', this.cache);

		var t = (typeof e.touches!='undefined') ? e.touches[0] : e;

		// set default position
		var x = Event.pointerX(t) - this.x;
		var y = Event.pointerY(t) - this.y;


		// context
		//this.context.save();
		this.context.beginPath();

		// move to starting point
		this.context.moveTo(x, y);

		this.history.drawing_dots = {};
		this.history.drawing_dots.thickness = this.context.lineWidth;
		this.history.drawing_dots.color = this.context.strokeStyle;
		this.history.drawing_dots.opacity = this.context.globalAlpha;
		this.history.drawing_dots.xarray = [];
		this.history.drawing_dots.yarray = [];
		this.history.drawing_dots.xarray.push(x);
		this.history.drawing_dots.yarray.push(y);

	},
	moveEvent:  function(e){
		e.preventDefault();
		if(this.f_draw){
			var t = (typeof e.touches!='undefined') ? e.touches[0] : e;
			var x = Event.pointerX(t) - this.x;
			var y = Event.pointerY(t) - this.y;
			this.context.lineTo(x, y);
			this.context.stroke();
			this.history.drawing_dots.xarray.push(x);
			this.history.drawing_dots.yarray.push(y);
		}
	},

	// Stop draw
	end: function(e){
		//if(this.check2Touch(e)) return;
		if(this.history.count()>=140) return;
		e.preventDefault();
		this.context.stroke();
	  	this.context.closePath();
		this.history.save(this.history.drawing_dots);
		if(this.f_draw){
			$(this.canvas).unbind('mousemove', this.cache);
			$(this.canvas).unbind('touchmove', this.cache);
			this.f_draw = false;
		}
	},
  	save : function(){
		var PNG = this.canvas.toDataURL('image/png').replace(/^.*,/, '');
		/*
		var img = new Image();
		img.src = PNG;
		document.body.appendChild(img);
		window.scrollTo(0, 400);
		*/

		var url = '/api/upload_from_canvas';
		var params = PNG;

		$.post(url, params, function(data){
			log(data)
			if(data.stat == 'ok'){
				$('#imageurl').val(data.url);
				$('#form').submit();
			}else{
				alert("Can not save the image. Please keep this page and try again.");
			}
		}, 'json');
  	},
	clear : function(){
		this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
	},
	clearall :function(){
		this.history.clearall();
	},
	undo: function(){
		this.history.undo();
		setTimeout(function(){
			this.setStroke();
		}.binds(this), 500)
	},
	redraw: function(){
		this.clear();
		this.history.redraw();
		this.setStroke();
	},
	check2Touch : function(e){
		if(typeof e.touches!='undefined'){
			if(e.touches.length > 1){
				log('2touch')
				return true;
			}else{
				return false;
			}
		}

  	}
};

var History = Class.create();
History.prototype = {
	initialize: function(canvas, context){
		this.drawing_dots = {};
		this.history = [];
		this.canvas = canvas;
		this.context = context;
	},
	count : function(){
		return this.history.length;
	},
	clear : function(){
		this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
	},
	undo : function(){
		this.history.pop();
		if(picurl == ''){
			this.clear();
			this.drawall();
		}else{
			this.clear();
			setPic(this.drawall.binds(this));
		}
		this.setleftstrokes();
	},
	redraw :function(){
		if(picurl == ''){
			this.clear();
			this.drawall();
		}else{
			this.clear();
			setPic(this.drawall.binds(this));
		}
	},
	 save : function(){
		this.history.push(this.drawing_dots);
		
		this.setleftstrokes();
	},
	clearall : function(){
		this.history = [];
		this.clear();
		picurl = '';
		this.setleftstrokes();
	},
	setleftstrokes : function (){
		var val = 140 - this.history.length;
		if (val <= 10){
			val = '<span style="color:red">' + val + '</span>';
		}
		
		$('#left_strokes').html(val);
		$('#stroke_count').val(140 - val);
	},
	drawall : function(){
		for (var i=0, l=this.count(); i<l; i++){
			this.context.beginPath();
			this.context.strokeStyle = this.history[i].color;
			this.context.lineWidth = this.history[i].thickness;
			this.context.globalAlpha = this.history[i].opacity;
			var xarray = this.history[i].xarray;
			var yarray = this.history[i].yarray;
			this.context.moveTo(xarray[0],yarray[0]);
			for (var d=1, dl=xarray.length;d<dl;d++){
				this.context.lineTo(xarray[d],yarray[d]);
			}
			this.context.stroke();
		  	this.context.closePath();
		}
	}
};

function setPic(func){
	var img = new Image();
	img.src = picurl;
	img.onload = function(){
		twitpaint.context.globalAlpha = 1;
		twitpaint.context.drawImage(img, 0, 0);
		if(typeof func == 'function'){
			func();
		}
	}
}

function postTwitter(showlogin, e){
	e.preventDefault();
	if (showlogin){
		$('#postbtn').hide();
		$('#loginform').show();
		$('#username').focus();
	}else{
		twitpaint.save();
	}
}

function limitChars(target,maxlength) {
    if (target.value.length > maxlength ) {
        target.value = target.value.substr(0,maxlength);
	    target.focus();
    }
}

// init
$(function(){
	twitpaint = new Canvas($('canvas')[0], 0);
	setPic();
	$('#clear').click(function(){
		twitpaint.clearall();
	});
	$('#undo').click(function(){
		twitpaint.undo();
	});

});
