(function($) {

	var defaults = { anchor : '', maxMetro: 1, preCall : '', startId: '', callBack: ''};

	$.fn.metromap = function(params){
		var options = $.extend({}, defaults, params);
		options.prefix = getPrefix(0000,9999);
		init(this);

		function init(e) {
			return e.each(function(){
				$(this).click(function(){
					if (options.preCall) {
						options.startId = eval(options.preCall)();
					}
					open_map($(this));
					return false;
				});
			});
		}

		function get_metros() {
			var vals = $('#' + options.prefix + '_form_metro').val();
			return clean_arr(vals.split(','));
		}
		
		function set_metros(arr) {
			$('#' + options.prefix + '_form_metro').val(implode(',',arr));
		}
	
		function clean_arr(arr) {
			var a = new Array;
			for(var i = 0, l = arr.length; i < l; i++)  {
				if(arr[i]) {
					a[a.length] = arr[i];
				}
			}
			return a;
		}

		function in_array(need, arr) {
			for(var i = 0, l = arr.length; i < l; i++)  {
				if(arr[i] == need) {
					return true;
				}
			}
			return false;
		}

		function get_posistion(element) {
			var offset = element.offset();
			return {left: offset.left , top: offset.top}
		}

		function open_map(element) {
			var pos = get_posistion(element);
			var popupW = (options.maxMetro == 1)? 640 : 940;
			popupbox = new popupBox({width: popupW, top: pos.top, prefix: options.prefix});
			popupbox.openBox();
			$.post(
				'/metromap/',
				{ 'total' : options.maxMetro, 'prefix' : options.prefix },
				function(data){
					popupbox.fillBox(data);
					addStartId();
					listen();
					return false;
				}
			);
			return false;
		}

		function addStartId(){
			if(options.startId.length > 0) {
				set_metros(options.startId);

				for(i = 0; i < options.startId.length; i++){
					var id = options.startId[i];
					var el = $(".station[rel='"+id+"']");
					var name = el.attr('title');
	
					el.addClass('selected_station').css({
						'background-position': '-' + parseInt(el.css('left')) + 'px -' + parseInt(el.css('top')) + 'px'
					});

					$('#' + options.prefix + '_ul_selected_metro').append($('<li id="li_' + id + '">' + name + '<span class="close_me" rel="' + id + '"></span></li>'));
				}
				listenCloser();
		
				$('#' + options.prefix + '_submit_metro').show();
			}
		}

		function getPrefix(min, max) {
			return Math.floor(Math.random() * (max - min + 1)) + min;
		}

		function closeMap() {
			popupbox.closePopup();
		}

		function scrollToForm(event) {
			if($(options.anchor).size() > 0) {
				var position = $(options.anchor).offset().top;
				var top = $(document).scrollTop();
				
				if(position < top){
					$('html, body').stop().animate({ scrollTop: position },0);
				}
			}
			event.preventDefault();
		}

		function killListen(){
			$('#' + options.prefix + '_clear_all_metro').unbind('click');
			$('#' + options.prefix + '_cancel_metro').unbind('click');
			$('#' + options.prefix + '_close_metro').unbind('click');
			$('#' + options.prefix + '_submit_metro').unbind('click');
			$('.station').unbind();
			killListenCloser();
		}
		
		function clearAndClose(event) {
			metros = get_metros();
			eval(options.callBack)(metros, options.typename);
			closeMap();
			scrollToForm(event);
		}
	
		function listen() {
			$('#' + options.prefix + '_clear_all_metro').click(function(event){
				$('#' + options.prefix + '_form_metro').val('');
				$('#' + options.prefix + '_ul_selected_metro').html('');
				$('#' + options.prefix + '_popupError').hide();
				//$('#' + options.prefix + '_submit_metro').hide();
				$('.selected_station').remove();
				return false;
			});
			
			$('#' + options.prefix + '_close').click(function(event){
				popupbox.closePopup();
				return false;
			});
			
			$('#' + options.prefix + '_cancel_metro').click(function(event){
				popupbox.closePopup();
				return false;
			});
			
			$('#' + options.prefix + '_submit_metro').click(function(event){
				clearAndClose(event);
				return false;
			});

			$('.station').click(function(event){
				var name = $(this).attr('title');
				var id = $(this).attr('rel');
				
				if($(this).hasClass('selected_station')) {
					killMetros(id);
				} else {
					$(this).addClass('selected_station').css({
						'background-position': '-' + parseInt($(this).css('left')) + 'px -' + parseInt($(this).css('top')) + 'px'
					});
					
					if(options.maxMetro == 1){
						
						eval(options.callBack)([$(this).attr('rel')],options.typename);
						closeMap();
						scrollToForm(event);
					}else{
						var metros = get_metros();
						
						if(metros.length >= options.maxMetro) {
							$('#' + options.prefix + '_popupError').show();
						} else {
							if(!in_array(id, metros)){
								$('#' + options.prefix + '_ul_selected_metro').append($('<li id="li_' + id + '">' + name + '<span class="close_me" rel="' + id + '"></span></li>'));
								metros[metros.length] = id;
								$('#' + options.prefix + '_form_metro').val(metros.join(','));
								listenCloser();
							}
						}
						$('#' + options.prefix + '_submit_metro').show();
					}
				}

				return false;
			}).mouseover(function(){$(this).addClass('border-bottom')}).mouseout(function(){$(this).removeClass('border-bottom')});
			
			$('.metro_arrow').click(function(){
				checkline($(this).attr('abbr').split(','));
				return false;
			});
			
			$('.metro_line').click(function(){
				checkline($(this).attr('rel').split(','))
				return false;
			});
		}
		
		function checkline(st) {
			var stlen = st.length;
				
			var total = 0;
			for(var i = 0; i < stlen; i++) {
				if( $('#a_' + st[i]).hasClass('selected_station') ){
					var on = true;
					var total = total + 1;
				}
			}
			
			if( total == stlen) {
				for(var i = 0; i < stlen; i++) {
					var id = st[i];
					killMetros(id);
				}
				
				if (get_metros().length == 0) {
					$('#' + options.prefix + '_submit_metro').hide();
				}
			} else {
				var metros = get_metros();

				for(var i = 0; i < stlen; i++) {
					var id = st[i];
					
					if(!in_array(id, metros)){
						var el = $('#a_' + id);
						$('#' + options.prefix + '_ul_selected_metro').append($('<li id="li_' + id + '">' + el.attr('title') + '<span class="close_me" rel="' + id + '"></span></li>'));
						metros[metros.length] = id;
						$('#' + options.prefix + '_form_metro').val(metros.join(','));
					
						el.addClass('selected_station').css({
							'background-position': '-' + parseInt(el.css('left')) + 'px -' + parseInt(el.css('top')) + 'px'
						});
						listenCloser();
					}
				}
				
				$('#' + options.prefix + '_submit_metro').show();
			}
		}

		function killListenCloser() {
			$('#' + options.prefix + '_ul_selected_metro li .close_me').unbind('click');
		}
		
		function listenCloser() {
			killListenCloser();
			
			$('#' + options.prefix + '_ul_selected_metro li .close_me').click(function(){
				var id = $(this).attr('rel');
				$(".station[rel='"+id+"']").removeClass('selected_station');
				killMetros(id);
			});	
		}
		
		function killMetros(id) {
			$('#li_' + id).remove();
			$('#a_' + id).removeClass('selected_station');
			
			var new_metros = remove_metro(id, get_metros());
			$('#' + options.prefix + '_form_metro').val(new_metros.join(','));
			
			if(new_metros.length < options.maxMetro){
				$('#' + options.prefix + '_popupError').hide();
			}
		}
		
		function remove_metro(id, arr){
			a = new Array;
			for(var i = 0, l = arr.length; i < l; i++)  {
				if(arr[i] != id) {
					a[a.length] = arr[i];
				}
			}
			return a;
		}
	};
})(jQuery);
