
;(function($) {

	$.widget("ui.stringCheckbox", $.extend({
	
	    get: function() {
			return this.values ? this.values: []
	    },
	
		lazyRefreshOptions: function() {
			this.refreshOptions();
			this.lazyRefreshOptionsDone = true
		},
	
		refreshOptions: function() {
	
	        var o = this.element[0]
	
			var opts = this._getData('options')
	
	        //console.log("%d refreshOptions: %o", this.getId(), opts)
	
			//this.need_hide = true
			this.is_focus = false
	
	    	$('#' + o.id + '_list').remove();
	
	
	        var html = ['<div class="checkbox_list_wrap hide" id="' + o.id + '_list"> \
	            <ul class="checkbox_list"> \
	            <li class="even"><a href="javascript:void(0)" title="Любое значение" id="'+this.getId()+'-any">'+this._getData('empty_title')+'</a> \
	            <div class="stringCheckbox-close" id="'+this.getId()+'-close"></div> \
	            </li>'];
	
			var has_title = false
	
			var i=0;
			var c=1;
			if (!opts.best_idx) opts.best_idx = 999
			for(var prop in opts.data) {
	
				var name = opts.data[prop].name
				var title = opts.data[prop].title
				if (title) has_title = true
	
				if (i==opts.best_idx) {
					html.push('<li class="' + (c++%2 == 0 ? 'even' : 'odd') + '"><a href="javascript:void(0)" id="'+this.getId()+'-left">...остальные...</a></li>')
				}
	
				// set display style, not class to make sure it won't be overridden by css
				html.push('<li class="' + (c++%2 == 0 ? 'even' : 'odd') + '"'+(i>=opts.best_idx ? ' style="display:none"':'')+'><label'+(title ? ' title="'+title+'"' : '')+' for="'+o.id+prop+'"> \
					<input type="checkbox" value="'+prop+'" name="'+o.id+prop+'" id="'+o.id+prop+'"/> - '+name +'</label> \
				</li>')
				i++
			}
			if (has_title) {
				// help will be shown here
				html.push('<li class="autohelp">Наведите на неизвестное обозначение курсор мыши.</li>')
			}
	        html.push('</ul></div>');
	
	
	        $(html.join('')).appendTo('body');
	
			var $container = this.$container = $(document.getElementById(o.id + '_list'))
	
			this.leftLink = $('#'+this.getId()+'-left')
			if (has_title) {
				// help will be shown on .autohelp element
				$('label', $container).autohelp('.autohelp');
			}
	
			var self = this
	
			$('input', $container).click(
				function() {
					//self.need_hide = false;
					self.set(self.getInputValues())
				}
			);
	
			this.leftLink.parent().click(
				function(e) {
					self.showLeft()
					self.leftLink.blur()
				}
			)
	
			var anyLink = $('#'+this.getId()+'-any')
			anyLink.click(
					function() {
						this.blur()
						self.set([])
						self.close()
					}
				)
		
			var closer = $('#'+this.getId()+'-close')
		 	closer.click(
					function() {
						this.blur()
						self.close()
					}
				)
		
		
		    $('li',$container).hover(
		      function(){$(this).addClass("over");},
		      function(){$(this).removeClass("over");}
		    );
	
			this.renderInputValues()
	
	
		},
	
		showLeft: function() {
			if (this.leftShown) return
	
			o = this.leftLink.parent()
			o.nextAll().each(function (k,v) {
				v.style.display = '';
			})
			this.leftLink.html('остальные:')
			o.addClass('selectCheckbox-left-pressed')
	
			this.leftShown = true
		},
	
		_init: function() {
			
			this.init.apply(this, arguments)
		},
	
	
		init: function() {
			$.widget.prototype._init.apply(this,arguments)
			this.ajaxController = new AjaxController(this, this._getData('sendRequestPrefix'), this._getData('sendRequestPostfix'))
	
			var self = this
	
			this.clearElem = $('#'+this.getId()+'Clear')
	
			this.clearElem.click(
				function() {
					self.set()
				}
			)
	
			this.element.click(
				function(){
	
					this.blur()
	
					if (!self.lazyRefreshOptionsDone) self.lazyRefreshOptions()
	
					if(self.$container.isShow())
						self.close();
					else
						self.open();
	
				}
			)
	
			if (this._getData('options')) {
				//this.refreshOptions()
				this.set(this._getData('selectedValues'))
	    	}
	
			this.setHiders(true)
	
		},
	
		setPendingValues: function(values) {
			//console.log("%d setPendingvalues %s", this.getId(), values)
			//console.trace()
			this.pendingValues = values
		},
	
		hasPendingValues: function() {
			
			return !!this.pendingValues
		},
	
	
	
		// renders descr & inputs, set this.value
		set: function(values) {
			var data = this._getData('options').data
	
			//console.log("%d set %s", this.getId(), values)
	
			var oldValues = this.values
	
			if (typeof values == 'string') {
				values = values.split('-')
			}
	
			this.values = []
			if (values) {
				// clear values not in our data
				// e.g possibly region that WAS active before -> disappeared now
				for(var i=0;i<values.length; i++) {
					if (data[values[i]]) {
						this.values.push(values[i])
					}
				}
			}
	
			//console.log("%d set %s", this.getId(), this.values)
	
	
	
	
			// no sense in setting values while we loading new options
			if (this.lazyRefreshOptionsDone) {
				this.renderInputValues()
			}
	
			this.renderValues()
	
	
			this.element.triggerHandler('select', [values, oldValues])
	
		},
	
		renderInputValues: function() {
			var values = this.values
	
			vals = {}
			for (var i=0;i<values.length;i++) {
				vals[values[i]] = true
			}
	
			var self = this
			var idx = this._getData('options').best_idx
			$('input', this.$container).each(
				function(i, oo) {
					oo.checked = vals[oo.value] ? true: false
					// show all if any is checked
					if (i>=idx && oo.checked && !self.leftShown) {
						self.showLeft()
					}
				}
			);
		},
	
	
	    getInputValues: function() {
	
	        var values = [];
			$('input', this.$container).each(
				function(i, oo) {
					if(oo.checked)
						values.push(oo.value)
				}
			);
	
			return values
	    },
	
		// on close set(input vals)
		close: function() {
			if (!this.isShown) return
	
			//if(this.need_hide) {
				this.$container.hide();
	
				this.isShown = false
				//fixIE.hide();
				floatWidget.activePop(this)
			//}
	
			//this.need_hide = true;
	
	        var values = this.getInputValues()
	
			this.set(values)
	
		},
	
		open: function() {
			//this.need_hide = true
			//fixIE.show();
			floatWidget.activePush(this)
	
			//$container.css("top", $descr.outerHeight()).show();
			this.$container.css("left", this.element.offset().left).css("top", this.element.offset().top + this.element.outerHeight()).show();
			this.isShown = true
		},
	
	
		renderValues: function() {
			var self = this
	
			var res = ''
	
			var end = ' или '
	
			var opts = this._getData('options')
	
			// traversing not values.each, but opts.each
			// to keep rendered values order same as in opts, not same as (probably wrong) in values given
			if (this.values) {
				var vals = {}
				for(var i=0; i<this.values.length;i++) {
					vals[this.values[i]] = true
				}
	
				var i=0
				for(var prop in opts.data) {
					if (!vals[prop]) continue
	
					res += opts.data[prop].name + ((i + 2 < this.values.length) ? ', ' : end);
					i++
				}
			}
	
			this.clearElem[res.length ? 'show':'hide']()
	
	
			res = res.length > 0 ? res.substring(0, res.length - end.length) : this._getData('empty_title')
	
			this.element.attr('title', res)
	
			this.element.html($.trunc(res, 40));
		},
	
		onLoaded: function(data) {
			//console.log("%d loadOptions loader callback pendingValues: %s", self.getId(), self.pendingValues)
			
			if (data) {
				
				//console.log("%d loadOptions loader callback: %o", self.getId(), data)
				this._setData('options', data)
				this.lazyRefreshOptionsDone = false
				//self.refreshOptions()
	
				this.set(this.pendingValues || [])
			} else {
			}
	
			this.pendingValues = null
		},
	
		loadOptions: function(req) {
	        //console.log("%d loadOptions",this.getId())
			this.ajaxController.sendRequest(req)
	    }
	
	
	}, floatWidgetMixin, stringLoadingWidgetMixin))
	
	$.extend($.ui.stringCheckbox, {
		getter: 'hasPendingValues get getInputValues'
	});

})(jQuery);
