// TODO
//
////////////////////////////////

Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

Function.prototype.bindEvent = function(object) {
  var __method = this, args = $A(arguments), object = args.shift();
  return function(event) {
    return __method.apply(object, [( event || window.event)].concat(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, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

fms = {
	version: '0.1',

	serializeUri: function(uri, parameters) {
		
		if (uri.match(/\?$/))
			uri = uri + '&';
		else
			uri = uri +'?';

		for ( var name in parameters) {
			uri = uri + name + '=' + encodeURI(parameters[name]) + '&';			
		}
		uri = uri.replace(/&$/, '');
		return uri;
	},
	
        ajax : {
                init: function(options) // конструктор
                {

                        this.options = {
                                //async: true,
                                cache: false,
                                //contentType: 'application/x-www-form-urlencoded',
                                //processData: true,
                                dataType: 'json',
                                type: 'POST',
				timeout: 5000
                        };
                        //this.options = Fms.extend(this.options, options);

                        $.ajaxSetup(this.options);

                        this.elements = new Array();
                        this.objects = new Array();
                },

                send: function(options) // инициализация аякса
                {

                        options.error = function(xhr, textStatus, errorThrown)
                        {
                                fms.error.show('Ошибка сервера: ' + textStatus + errorThrown);
                        };

                        options.success = function(data, textStatus)
                        {

                        	for (var i = 0; i < data.length; i++) {

					var chunk = data[i];

                                        if ( chunk.type == 'object') {
                                        	fms.ajax.objects[chunk.id].ajaxUpdate(chunk);
	                                } else if (chunk.type == 'element') {
        	                                fms.ajax.elements[elementId].html(chunk.data);
                                        } else if (chunk.type == 'server_error') {
                	                        fms.error.show('Ошибка сервера:' + chunk.data);
                                        }
				}
                        };
			
			$.ajax(options);
                },
	
		addObject: function(id, obj) // регистрация объекта в движке
		{
			if (obj) 
				this.objects[id] = obj;
		},
		
		addElement: function(id, element) // регистрайия html элемента 
		{
			if ($(element).get(0)) 
				this.elements[id] = $(element).get(0);
		}
	},

	extend: function(destination, source) {
		for (var property in source) {
			destination[property] = source[property];
		 }
		return destination;
	}

};
fms.ajax.init();

//
fms.Event = {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,

  element: function(event) {
    return event.target || event.srcElement;
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointerX: function(event) {
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

  pointerY: function(event) {
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

  stop: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  }
};


fms.Message = function (id) {
		if (id) {
			this.id = id;	
			$('#'+id).click(this.click.bindEvent(this));
		} else {
			this.id = false;
		}
};
fms.Message.prototype = {
	show: function (msg) {
		if (this.id) {
			var li = $('<li></li>').html('<pre>'+msg+'</pre>').prependTo('#'+this.id+' ul').get(0);		
			if (this.useEffects)
				$(li).fadeOut(500, function() {$(this).fadeIn(500)});
		} else { 
			alert(msg);
		}
	},

	ajaxUpdate: function(msg) {
		this.show(msg);
	},

	click: function() {
		//$('#'+this.id).css('
	}	

};

fms.error = new fms.Message();
fms.ajax.addObject('message', fms.error);

fms.Upload = function (inputId, uri) {
		
		this.uri = uri;
		name = $('#'+inputId).attr('name');
	
		this.frameName = 'upload' + Math.floor(Math.random() * 99999);

		$('#'+inputId).replaceWith('<div><iframe style="display:none;" src="about:blank" id="'+this.frameName+'" name="'+this.frameName+'"></iframe><form id="form_'+this.frameName+'" action="" target="'+this.frameName+'" method="post" enctype="multipart/form-data"><input type="file" name="'+name+'" id="'+inputId+'" /></form></div>');
		this.frame = $('#'+this.frameName).get(0);
		this.frame.parentObj = this;
		$(this.frame).load(function() {this.parentObj.onComplete();});
		this.form = $('#form_'+this.frameName).get(0);
};
fms.Upload.prototype = {
	onComplete: function() {
		var data;
		if (this.frame.contentDocument) {
			data = this.frame.contentDocument;
		} else if (this.frame.contentWindow) {
			data = this.frame.contentWindow.document;
		} else {
			fms.error.show('Ошибка на сервере!');
			return;
		}
		data = data.documentElement.childNodes[1]
		//data = data.childNodes[0];
		//alert(data.tagName);		
		if (data)
			data = $(data).text();
		else
			return;
		
		try {
			data = eval(data);
		} catch(err) {
			fms.error.show("Ошибка трансляции данных! \n\n" + data);
		}

		if (!data) return;

		for (var i = 0; i < data.length; i++) {

			var chunk = data[i];
			
                        if ( chunk.type == 'object') {
                		fms.ajax.objects[chunk.id].ajaxUpdate(chunk);
	                } else if (chunk.type == 'element') {
        	        	fms.ajax.elements[elementId].html(chunk.data);
                        } else if (chunk.type == 'server_error') {
                	        fms.error.show('Ошибка сервера:' + chunk.data);
                        }
		}

		return;	
		var list = eval(Fms.getContentAsString(doc));
		
		if (!Fms.getContentAsString(doc))
			return;
		
		for (var i = 0; i < list.length; i++) {
			var response = list[i];
			var elementType = response.type;
			var elementId = response.id;
			if (elementType == 'object') {
				fms.ajaxObjects[elementId].ajaxUpdate(response);
			} else if (elementType == 'element') {
				var el = fme.ajaxElements[elementId];
				el.innerHTML = Fms.getContentAsString(response);
			} else if (elementType == 'server_error') {
				alert('Server error!\n' + response.content);
			}
		}
	},

	submit : function(parameters) {
		$(this.form).attr('action', fms.serializeUri(this.uri, parameters));
		//alert( fms.serializeUri(this.uri, parameters));
		this.form.submit();
	}

};

