function List(a){this.config=a;this.props=a.props;this.main=a.main;this.selectedLine=-2;this.lines=[];a.getItems||(a.getItems=function(){return a.items});a.getItemProp||(a.getItemProp=function(b,c){return a.getItem(b)[c]});a.setItemProp||(a.setItemProp=function(b,c,d){a.getItem(b)[c]=d});a.getItem||(a.getItem=function(b){return a.getItems()[b]});a.move||(a.move=function(b,c){if(b!=c&&b>=0&&c>=0&&b<this.count()&&c<this.count()){var d=a.getItems(),e=d[b];d.splice(b,1);d.splice(c,0,e)}});a.insert||(a.insert=
function(b,c){a.getItems().splice(b,0,c)});a.remove||(a.remove=function(b){a.move(b,a.count()-1);a.getItems().pop()});a.validate||(a.validate=function(){return true});a.count||(a.count=function(){return a.getItems().length});a.patch||(a.patch=function(b,c){for(var d in c)a.setItemProp(b,d,c[d])});a.defaultValue||(a.defaultValue={});a.main.addClass("list")}List.ids={noline:-1};List.types={};
List.prototype={init:function(){with(this){if(this.inited)return;this.inited=!0;this.headergroup=$('<div class="headers"></div>');for(var a=0;a<props.length;++a){var b=$('<div class="header"></div>').attr("property",props[a].property).html(props[a].header);headergroup.append(b)}this.scrolls=$("<div>").addClass("listscroll");this.contents=$('<div class="listitems"></div>').appendTo(scrolls);scrolls.scroll(function(){headergroup.css("left",-scrolls.scrollLeft()+"px")});contents.click(function(a){a.target==
contents[0]&&selectLine(List.ids.noline)});$(main).append(headergroup).append(scrolls);a=this.main.height()-this.headergroup.outerHeight();this.scrolls.height(a);load();selectLine(List.ids.noline)}},editNewLine:function(){this.startEdit(this.lines[this.lines.length-1])},updatePropDisplay:function(a,b){var c=b.property;obj=$("[property="+c+"]",a);var d=obj[0].listdata,e=Number(a.attr("row"));if(e==this.config.count()){if(c=this.config.defaultValue[c])d.value=c;obj.trigger("createNew")}else d.value=
this.config.getItemProp(e,c),obj.trigger("update")},updateLine:function(a){for(var b=0;b<this.props.length;++b)this.updatePropDisplay(a,this.props[b]);Number(a.attr("row"))<this.config.count()?a.trigger("update"):a.addClass("newline")},createLine:function(){with(this){var a=$("<div></div>").addClass("itemline"),b=$("<div>");a.append(b);for(var c=0;c<props.length;++c){var d=props[c],e=$("<div></div>").attr("property",d.property).addClass("listvalue").attr("tabindex",-1);new List.types[d.type](e,d);
var h={list:this,line:a,prop:d},f;for(f in d.events)e.bind(f,h,d.events[f]);e.bind("change",function(){validate(a);return!0});e.bind("keyup",function(b){27==b.keyCode&&cancelEdit(a)});e.trigger("create");b.append(e)}a.click(function(){startEdit(a)});a.focusin(function(){startEdit(a)});a.focusout(function(){finishEdit(a)});for(f in this.config.lineEvents)a.bind(f,{list:this,line:a},this.config.lineEvents[f]);var g=this;a.bind("updating",function(){$(g).trigger("updating")});a.bind("updated",function(){$(g).trigger("updated")});
this.bindId(a,this.lines.length);this.lines.push(a);a.appendTo(this.contents);return a}},refresh:function(a){var b=!1;void 0===a&&(b=!0,a=[]);for(var c=this.lines.length;c<=this.config.count();++c)this.createLine(),a.push(c);for(;this.lines.length>this.config.count()+1;)this.lines.pop().remove();$(".newline",this.contents).removeClass("newline");this.lines[this.lines.length-1].addClass("newline");if(b)for(c=0;c<this.lines.length;++c)this.updateLine(this.lines[c]);else for(c=0;c<a.length;++c)this.updateLine(this.lines[a[c]])},
load:function(){this.contents.empty();this.lines=[];this.refresh()},bindId:function(a,b){a.attr("row",b)},getLineNewValue:function(a){for(var b={},c=0;c<this.props.length;++c)this.getPropValue(a,b,this.props[c]);return b},getPropValue:function(a,b,c){c=c.property;obj=$("[property="+c+"]",a);a=obj[0].listdata.value;void 0!==a&&(b[c]=a);return a},startEdit:function(a){if(!a.hasClass("editing")){a.addClass("editing");this.showLine(a);this.selectLine(a);var b=this;setTimeout(function(){a[0].contains(document.activeElement)||
$(".valinput",a).first().focus();b.validate(a)},50)}},finishEdit:function(a){var b=this;setTimeout(function(){with(b){if(a[0].contains(document.activeElement))return;if(isValid(a)){var c=Number(a.attr("row")),d=getLineNewValue(a);a.hasClass("newline")?($(b).trigger("updating"),config.insert(c,d)||(a.removeClass("newline"),b.selectLine(a),$(b).trigger("add",c),addNewLine())):(a.trigger("updating"),config.patch(c,d));a.trigger("updated")}cancelEdit(a)}},50)},cancelEdit:function(a){a.removeClass("editing");
a.removeClass("error");var b=Number(a.attr("row"));b==this.config.count()&&this.selectedLine==b&&(this.selectedLine=List.ids.noline);this.updateLine(a)},addNewLine:function(){with(this){var a=$(".newline",contents);a.length||(a=createLine().addClass("newline"));return a}},isValid:function(a){var b=Number(a.attr("row")),a=this.getLineNewValue(a);return valid=this.config.validate(b,a)},validate:function(a){this.isValid(a)?a.removeClass("error"):a.addClass("error")},move:function(a,b,c){var d=this.config.count();
if(!(a==b||0>a||0>b||a>=d||b>=d)){this.config.move(a,b);for(d=Math.min(a,b);d<=Math.max(a,b);++d)this.updateLine(this.getLine(d));c&&(this.selectedLine==a?this.selectLine(b):this.selectedLine==b&&this.selectLine(a))}},getLine:function(a){return 0>a||a>=this.lines.length?null:this.lines[a]},remove:function(a){a=Number(a);if(!(0>a||a>=this.config.count())){$(this).trigger("updating");var b=this.lines.length;this.getLine(a).trigger("removing");if(!this.config.remove(a)){this.getLine(b-1).remove();this.lines.pop();
for(var c=a;c<b-1;++c)this.updateLine(this.getLine(c));a>=b-2?this.selectLine(a):this.selectLine(List.ids.noline);$(this).trigger("updated")}}},selectLine:function(a){var b=a;"number"==typeof a?b=this.getLine(a):a=Number(b.attr("row"));b&&b.hasClass("newline")&&(b=null,a=List.ids.noline);if(this.selectedLine!=a){var c=this.getLine(this.selectedLine);c&&(this.cancelEdit(c),c.removeClass("selected"),c.trigger("deselect"),this.selectedLine=List.ids.noline);this.selectedLine=a;null!=b&&(b.addClass("selected"),
b.trigger("select"),this.showLine(b));$(this).trigger("select")}},showLine:function(a){var b=this.scrolls.scrollTop(),c=b+this.scrolls.height(),d=a.offset().top-this.contents.offset().top,a=d+a.height()+20;d<b?this.scrolls.scrollTop(d):a>c&&this.scrolls.scrollTop(Math.max(0,a-this.scrolls.height()))}};
