/*
backgrid
http://github.com/wyuenho/backgrid
Copyright (c) 2013 Jimmy Yuen Ho Wong
Licensed under the MIT @license.
*/
(function(e,t,i,r){"use strict";function n(e){return String.fromCharCode(e.charCodeAt(0)-32)+e.slice(1)}function o(e,t,i){var r=t-(e+"").length;r=0>r?0:r;for(var n="",o=0;r>o;o++)n+=i;return n+e}function s(e,t){for(var r=0;t.length>r;r++){var n=t[r];if(i.isUndefined(e[n]))throw new TypeError("'"+n+"' is required")}}function l(e,t){if(i.isString(e)){var r=i.map(e.split("-"),function(e){return n(e)}).join("")+t,o=h[r]||h.Extension[r];if(i.isUndefined(o))throw new ReferenceError("Class '"+r+"' not found");return o}return e}var a=e,h=e.Backgrid={VERSION:"0.2.0",Extension:{}},c=" \n\f\r \u2028\u2029";if(!String.prototype.trim||c.trim()){c="["+c+"]";var d=RegExp("^"+c+c+"*"),u=RegExp(c+c+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return(this+"").replace(d,"").replace(u,"")}}var m=h.CellFormatter=function(){};i.extend(m.prototype,{fromRaw:function(e){return e},toRaw:function(e){return e}});var p=h.NumberFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),0>this.decimals||this.decimals>20)throw new RangeError("decimals must be between 0 and 20")};p.prototype=new m,i.extend(p.prototype,{defaults:{decimals:2,decimalSeparator:".",orderSeparator:","},HUMANIZED_NUM_RE:/(\d)(?=(?:\d{3})+$)/g,fromRaw:function(e){if(i.isNull(e)||i.isUndefined(e))return"";e=e.toFixed(~~this.decimals);var t=e.split("."),r=t[0],n=t[1]?(this.decimalSeparator||".")+t[1]:"";return r.replace(this.HUMANIZED_NUM_RE,"$1"+this.orderSeparator)+n},toRaw:function(e){for(var t="",r=e.trim().split(this.orderSeparator),n=0;r.length>n;n++)t+=r[n];var o=t.split(this.decimalSeparator);t="";for(var n=0;o.length>n;n++)t=t+o[n]+".";"."===t[t.length-1]&&(t=t.slice(0,t.length-1));var s=1*(1*t).toFixed(~~this.decimals);return i.isNumber(s)&&!i.isNaN(s)?s:void 0}});var f=h.DatetimeFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),!this.includeDate&&!this.includeTime)throw Error("Either includeDate or includeTime must be true")};f.prototype=new m,i.extend(f.prototype,{defaults:{includeDate:!0,includeTime:!0,includeMilli:!1},DATE_RE:/^([+\-]?\d{4})-(\d{2})-(\d{2})$/,TIME_RE:/^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/,ISO_SPLITTER_RE:/T|Z| +/,_convert:function(e,t){e=e.trim();var r=e.split(this.ISO_SPLITTER_RE)||[],n=this.DATE_RE.test(r[0])?r[0]:"",s=n&&r[1]?r[1]:this.TIME_RE.test(r[0])?r[0]:"",l=this.DATE_RE.exec(n)||[],a=this.TIME_RE.exec(s)||[];if(t){if(this.includeDate&&i.isUndefined(l[0]))return;if(this.includeTime&&i.isUndefined(a[0]))return;if(!this.includeDate&&n)return;if(!this.includeTime&&s)return}var h=new Date(Date.UTC(1*l[1]||0,1*l[2]-1||0,1*l[3]||0,1*a[1]||null,1*a[2]||null,1*a[3]||null,1*a[5]||null)),c="";return this.includeDate&&(c=o(h.getUTCFullYear(),4,0)+"-"+o(h.getUTCMonth()+1,2,0)+"-"+o(h.getUTCDate(),2,0)),this.includeTime&&(c=c+(this.includeDate?"T":"")+o(h.getUTCHours(),2,0)+":"+o(h.getUTCMinutes(),2,0)+":"+o(h.getUTCSeconds(),2,0),this.includeMilli&&(c=c+"."+o(h.getUTCMilliseconds(),3,0))),this.includeDate&&this.includeTime&&(c+="Z"),c},fromRaw:function(e){return i.isNull(e)||i.isUndefined(e)?"":this._convert(e)},toRaw:function(e){return this._convert(e,!0)}});var g=h.StringFormatter=function(){};g.prototype=new m,i.extend(g.prototype,{fromRaw:function(e){return i.isUndefined(e)||i.isNull(e)?"":e+""}});var v=h.EmailFormatter=function(){};v.prototype=new m,i.extend(v.prototype,{toRaw:function(e){var t=e.trim().split("@");return 2===t.length&&i.all(t)?e:void 0}});var w=h.CellEditor=r.View.extend({initialize:function(e){s(e,["formatter","column","model"]),this.parent=e.parent,this.formatter=e.formatter,this.column=e.column,this.column instanceof T||(this.column=new T(this.column)),this.parent&&i.isFunction(this.parent.on)&&this.listenTo(this.parent,"backgrid:editing",this.postRender),this.listenTo(this,"backgrid:done",this.remove)},postRender:function(){return this.$el.focus(),this}}),y=h.InputCellEditor=w.extend({tagName:"input",attributes:{type:"text"},events:{blur:"saveOrCancel",keydown:"saveOrCancel"},initialize:function(e){w.prototype.initialize.apply(this,arguments),e.placeholder&&this.$el.attr("placeholder",e.placeholder)},render:function(){return this.$el.val(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this},saveOrCancel:function(e){var t=this.formatter,r=this.model,n=this.column;if(13===e.keyCode||9===e.keyCode||"blur"===e.type){e.preventDefault();var o=t.toRaw(this.$el.val());if(i.isUndefined(o)||!r.set(n.get("name"),o,{validate:!0})){if(this.trigger("backgrid:error",this),"blur"===e.type)var s=this,l=a.setTimeout(function(){s.$el.focus(),a.clearTimeout(l)},1)}else this.trigger("backgrid:done",this)}else 27===e.keyCode&&(e.stopPropagation(),this.trigger("backgrid:done",this))},postRender:function(){if("right"===this.$el.css("text-align")){var e=this.$el.val();this.$el.focus().val(null).val(e)}else this.$el.focus();return this}}),b=h.Cell=r.View.extend({tagName:"td",formatter:new m,editor:y,events:{click:"enterEditMode"},initialize:function(e){s(e,["model","column"]),this.column=e.column,this.column instanceof T||(this.column=new T(this.column)),this.formatter=l(this.formatter,"Formatter"),this.editor=l(this.editor,"CellEditor"),this.listenTo(this.model,"change:"+this.column.get("name"),function(){this.$el.hasClass("editor")||this.render()})},render:function(){return this.$el.empty(),this.$el.text(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this.delegateEvents(),this},enterEditMode:function(){this.column.get("editable")&&(this.currentEditor=new this.editor({parent:this,column:this.column,model:this.model,formatter:this.formatter}),this.trigger("backgrid:edit",this,this.currentEditor),this.listenTo(this.currentEditor,"backgrid:done",this.exitEditMode),this.listenTo(this.currentEditor,"backgrid:error",this.renderError),this.$el.empty(),this.undelegateEvents(),this.$el.append(this.currentEditor.$el),this.currentEditor.render(),this.$el.addClass("editor"),this.trigger("backgrid:editing",this,this.currentEditor))},renderError:function(){this.$el.addClass("error")},exitEditMode:function(){this.$el.removeClass("error"),this.stopListening(this.currentEditor),delete this.currentEditor,this.$el.removeClass("editor"),this.render(),this.delegateEvents()},remove:function(){return this.currentEditor&&(this.currentEditor.remove.apply(this,arguments),delete this.currentEditor),r.View.prototype.remove.apply(this,arguments)}}),E=h.StringCell=b.extend({className:"string-cell",formatter:new g});h.UriCell=b.extend({className:"uri-cell",render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:e,title:e,target:"_blank"}).text(e)),this.delegateEvents(),this}}),h.EmailCell=E.extend({className:"email-cell",formatter:new v,render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:"mailto:"+e,title:e}).text(e)),this.delegateEvents(),this}});var C=h.NumberCell=b.extend({className:"number-cell",decimals:p.prototype.defaults.decimals,decimalSeparator:p.prototype.defaults.decimalSeparator,orderSeparator:p.prototype.defaults.orderSeparator,formatter:p,initialize:function(){b.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({decimals:this.decimals,decimalSeparator:this.decimalSeparator,orderSeparator:this.orderSeparator})}});h.IntegerCell=C.extend({className:"integer-cell",decimals:0});var $=h.DatetimeCell=b.extend({className:"datetime-cell",includeDate:f.prototype.defaults.includeDate,includeTime:f.prototype.defaults.includeTime,includeMilli:f.prototype.defaults.includeMilli,formatter:f,initialize:function(){b.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({includeDate:this.includeDate,includeTime:this.includeTime,includeMilli:this.includeMilli});var e=this.includeDate?"YYYY-MM-DD":"";e+=this.includeDate&&this.includeTime?"T":"",e+=this.includeTime?"HH:mm:ss":"",e+=this.includeTime&&this.includeMilli?".SSS":"",this.editor=this.editor.extend({attributes:i.extend({},this.editor.prototype.attributes,this.editor.attributes,{placeholder:e})})}});h.DateCell=$.extend({className:"date-cell",includeTime:!1}),h.TimeCell=$.extend({className:"time-cell",includeDate:!1}),h.BooleanCell=b.extend({className:"boolean-cell",editor:i.template(" />'"),events:{click:"enterEditMode","blur input[type=checkbox]":"exitEditMode","change input[type=checkbox]":"save"},render:function(){return this.$el.empty(),this.currentEditor=t(this.editor({checked:this.formatter.fromRaw(this.model.get(this.column.get("name")))})),this.$el.append(this.currentEditor),this.delegateEvents(),this},enterEditMode:function(){this.$el.addClass("editor"),this.currentEditor.focus()},exitEditMode:function(){this.$el.removeClass("editor")},save:function(){var e=this.formatter.toRaw(this.currentEditor.prop("checked"));this.model.set(this.column.get("name"),e)}});var x=h.SelectCellEditor=w.extend({tagName:"select",events:{change:"save",blur:"close"},template:i.template(''),setOptionValues:function(e){this.optionValues=e},_renderOptions:function(e,t){for(var i="",r=0;e.length>r;r++)i+=this.template({text:e[r][0],value:e[r][1],selected:t==e[r][1]});return i},render:function(){this.$el.empty();var e=i.result(this,"optionValues"),r=this.model.get(this.column.get("name"));if(!i.isArray(e))throw TypeError("optionValues must be an array");for(var n=null,o=null,n=null,s=null,l=null,a=0;e.length>a;a++){var n=e[a];if(i.isArray(n))o=n[0],n=n[1],this.$el.append(this.template({text:o,value:n,selected:n==r}));else{if(!i.isObject(n))throw TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");s=n.name,l=t("",{label:s}),l.append(this._renderOptions(n.values,r)),this.$el.append(l)}}return this.delegateEvents(),this},save:function(){this.model.set(this.column.get("name"),this.formatter.toRaw(this.$el.val())),this.trigger("backgrid:done",this)},close:function(){this.trigger("backgrid:done",this)}});h.SelectCell=b.extend({className:"select-cell",editor:x,optionValues:void 0,initialize:function(){b.prototype.initialize.apply(this,arguments),s(this,["optionValues"]),this.optionValues=i.result(this,"optionValues"),this.listenTo(this,"backgrid:edit",this.setOptionValues)},setOptionValues:function(e,t){t.setOptionValues(this.optionValues)},render:function(){this.$el.empty();var e=this.optionValues,t=this.formatter.fromRaw(this.model.get(this.column.get("name")));try{if(!i.isArray(e)||i.isEmpty(e))throw new TypeError;for(var r=0;e.length>r;r++){var n=e[r];if(i.isArray(n)){var o=n[0],n=n[1];if(n==t){this.$el.append(o);break}}else{if(!i.isObject(n))throw new TypeError;for(var s=n.values,l=0;s.length>l;l++){var a=s[l];if(a[1]==t){this.$el.append(a[0]);break}}}}}catch(h){if(h instanceof TypeError)throw TypeError("'optionValues' must be of type {Array.|Array.<{name: string, values: Array.}>}");throw h}return this.delegateEvents(),this}});var T=h.Column=r.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,cell:void 0,headerCell:void 0},initialize:function(e){s(e,["cell","name"]),this.has("label")||this.set({label:this.get("name")},{silent:!0});var t=l(this.get("headerCell"),"HeaderCell"),i=l(this.get("cell"),"Cell");this.set({cell:i,headerCell:t},{silent:!0})}}),R=h.Columns=r.Collection.extend({model:T}),k=h.Row=r.View.extend({tagName:"tr",initOptionRequires:["columns","model"],initialize:function(e){s(e,this.initOptionRequires);var t=this.columns=e.columns;t instanceof r.Collection||(t=this.columns=new R(t));for(var i=this.cells=[],n=0;t.length>n;n++)i.push(this.makeCell(t.at(n),e));this.listenTo(t,"change:renderable",function(e,t){for(var r=0;i.length>r;r++){var n=i[r];n.column.get("name")==e.get("name")&&(t?n.$el.show():n.$el.hide())}}),this.listenTo(t,"add",function(t,r){var n=r.indexOf(t),o=this.makeCell(t,e);i.splice(n,0,o),o.column.get("renderable")||o.$el.hide();var s=this.$el;0===n?s.prepend(o.render().$el):n===r.length-1?s.append(o.render().$el):s.children().eq(n).before(o.render().$el)}),this.listenTo(t,"remove",function(e,t,r){i[r.index].remove(),i.splice(r.index,1)})},makeCell:function(e){return new(e.get("cell"))({column:e,model:this.model})},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.cells.length>t;t++){var i=this.cells[t];e.appendChild(i.render().el),i.column.get("renderable")||i.$el.hide()}return this.el.appendChild(e),this.delegateEvents(),this},remove:function(){for(var e=0;this.cells.length>e;e++){var t=this.cells[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}}),D=h.HeaderCell=r.View.extend({tagName:"th",events:{"click a":"onClick"},_direction:null,initialize:function(e){s(e,["column","collection"]),this.column=e.column,this.column instanceof T||(this.column=new T(this.column)),this.listenTo(r,"backgrid:sort",this._resetCellDirection)},direction:function(e){return arguments.length&&(this._direction&&this.$el.removeClass(this._direction),e&&this.$el.addClass(e),this._direction=e),this._direction},_resetCellDirection:function(e,t,i,r){r==this.collection&&(e!==this.column.get("name")?this.direction(null):this.direction(t))},onClick:function(e){e.preventDefault();var t=this.column.get("name");this.column.get("sortable")&&("ascending"===this.direction()?this.sort(t,"descending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:r>n?-1:1}):"descending"===this.direction()?this.sort(t,null):this.sort(t,"ascending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:n>r?-1:1}))},sort:function(e,t,i){i=i||this._cidComparator;var n=this.collection;if(r.PageableCollection&&n instanceof r.PageableCollection){var o;o="ascending"===t?-1:"descending"===t?1:null,n.setSorting(o?e:null,o),"client"==n.mode?(n.fullCollection.comparator||(n.fullCollection.comparator=i),n.fullCollection.sort()):n.fetch()}else n.comparator=i,n.sort();r.trigger("backgrid:sort",e,t,i,this.collection)},_cidComparator:function(e,t){var r=e.cid,n=t.cid;if(!i.isUndefined(r)&&!i.isUndefined(n)){if(r=1*r.slice(1),n=1*n.slice(1),n>r)return-1;if(r>n)return 1}return 0},render:function(){this.$el.empty();var e=t("").text(this.column.get("label")).append("");return this.$el.append(e),this.delegateEvents(),this}});h.HeaderRow=h.Row.extend({initOptionRequires:["columns","collection"],initialize:function(){h.Row.prototype.initialize.apply(this,arguments)},makeCell:function(e,t){var i=e.get("headerCell")||t.headerCell||D;return i=new i({column:e,collection:this.collection})}});var N=h.Header=r.View.extend({tagName:"thead",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new R(this.columns)),this.row=new h.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this.delegateEvents(),this},remove:function(){return this.row.remove.apply(this.row,arguments),r.View.prototype.remove.apply(this,arguments)}}),S=h.Body=r.View.extend({tagName:"tbody",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new R(this.columns)),this.row=e.row||k,this.rows=this.collection.map(function(e){var t=new this.row({columns:this.columns,model:e});return t},this);var t=this.collection;this.listenTo(t,"add",this.insertRow),this.listenTo(t,"remove",this.removeRow),this.listenTo(t,"sort",this.refresh),this.listenTo(t,"reset",this.refresh)},insertRow:function(e,t,n){if(!(t instanceof r.Collection||n))return this.collection.add(e,n=t),void 0;n=i.extend({render:!0},n||{});var o=new this.row({columns:this.columns,model:e}),s=t.indexOf(e);this.rows.splice(s,0,o);var l=this.$el,a=l.children(),h=o.render().$el;n.render&&(s>=a.length?l.append(h):a.eq(s).before(h))},removeRow:function(e,t,r){return r?((i.isUndefined(r.render)||r.render)&&this.rows[r.index].remove(),this.rows.splice(r.index,1),void 0):(this.collection.remove(e,r=t),void 0)},refresh:function(){for(var e=0;this.rows.length>e;e++)this.rows[e].remove();return this.rows=this.collection.map(function(e){var t=new this.row({columns:this.columns,model:e});return t},this),this.render(),r.trigger("backgrid:refresh",this),this},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.rows.length>t;t++){var i=this.rows[t];e.appendChild(i.render().el)}return this.el.appendChild(e),this.delegateEvents(),this},remove:function(){for(var e=0;this.rows.length>e;e++){var t=this.rows[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}});h.Footer=r.View.extend({tagName:"tfoot",initialize:function(e){s(e,["columns","collection"]),this.parent=e.parent,this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new h.Columns(this.columns))}}),h.Grid=r.View.extend({tagName:"table",className:"backgrid",header:N,body:S,footer:null,initialize:function(e){s(e,["columns","collection"]),e.columns instanceof r.Collection||(e.columns=new R(e.columns)),this.columns=e.columns,this.header=e.header||this.header,this.header=new this.header(e),this.body=e.body||this.body,this.body=new this.body(e),this.footer=e.footer||this.footer,this.footer&&(this.footer=new this.footer(e)),this.listenTo(this.columns,"reset",function(){this.header=new(this.header.remove().constructor)(e),this.body=new(this.body.remove().constructor)(e),this.footer&&(this.footer=new(this.footer.remove().constructor)(e)),this.render()})},insertRow:function(e,t,i){return this.body.insertRow(e,t,i)},removeRow:function(e,t,i){return this.body.removeRow(e,t,i)},insertColumn:function(e,t){return t=t||{render:!0},this.columns.add(e,t),this},removeColumn:function(e,t){return this.columns.remove(e,t),this},render:function(){return this.$el.empty(),this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.delegateEvents(),this.trigger("backgrid:rendered",this),this},remove:function(){return this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),r.View.prototype.remove.apply(this,arguments)}})})(this,jQuery,_,Backbone);