<script type="text/javascript">
/*
Copyright 2017 apHarmony

This file is part of jsHarmony.

jsHarmony is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

jsHarmony is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this package.  If not, see <http://www.gnu.org/licenses/>.
*/
(function(jsh){
  var modelid = '<%=model.id%>';
  var basemodelid = '<%=model._basemodel%>';
  
  <% if(model.topmost){ %>
  jsh.XModels = {};
  jsh.XBase = {};
  jsh.XModels_root = modelid;
  jsh.XPopups = {};
  jsh.is_popup = <%=xejs.iif('popup' in model,'true','false')%>;
  <% } %>
  <%-jslocals%>
  <%
  var curtab = null;
  if(model.tabs && model.tabs.length){
    var tab = _.find(model.tabs,function(tab){ return tab.selected; });
    if(tab) curtab = tab.modelid;
  }
  var bindings = model.bindings;
  if(model.topmost && (typeof bindings == 'undefined')){
    if((model.layout=='form-m')||(model.layout=='multisel')){
      _.each(model.fields, function(field){
        if(field.name && XExt.hasAction(field.actions,'F') && (field.name in jsh._GET) && jsh._GET[field.name]){
          if(!bindings) bindings = {};
          bindings[field.name] = "'" + XExt.escapeJS(jsh._GET[field.name]) + "'";
        }
      });
    }
  }
  %>
  var xmodel = jsh.XModels[modelid] = {
    id:modelid,
    namespace:'<%=model.namespace%>',
    class:'<%=model.class%>',
    controller: null,
    datamodel: null,
    fields: null,
    actions:'<%=model.actions%>',
    layout:'<%=model.layout%>',
    breadcrumbs_html:<%-JSON.stringify(model.breadcrumbs||null)%>,
    current_display_layout_name:'<%=model.current_display_layout_name||''%>',
    display_layouts:<%-(model.display_layouts)?JSON.stringify(model.display_layouts):'false'%>,
    enabled: true,
    title: <%-xejs.iif(model.title,JSON.stringify(model.title),"''")%>,
    caption:<%-JSON.stringify(model.caption)%>,
    parent:<%-(!parent?'null':"'"+parent.id+"'")%>,
    topmost:<%=model.topmost?'true':'false'%>,
    module:<%-JSON.stringify(model.module)%>,
    module_namespace:<%-JSON.stringify(model.module_namespace)%>,
    bindings:<% if(!bindings){ %>null<% } else { 
      %>{<%
      if(model.topmost) _.each(model.fields,function(field){ if(field.name in bindings) {%><%=field['name']%>: function(){return jsh.XExt.LiteralOrLookup(<%-JSON.stringify(bindings[field['name']])%>,jsh._GET);},<%	}});
      else if(typeof bindings != 'undefined') _.each(bindings,function(val,key){%><%=key%>: function(){ var xparentmodel = jsh.XModels['<%=parent.id%>']; return jsh.XExt.LiteralOrLookup(<%-JSON.stringify(val)%>,xparentmodel.controller.form.Data,xparentmodel);},<%}); 
      %>}<%
    } %>,
    binding_fields:<%-JSON.stringify(bindings||{})%>,
    constant_bindings:<%-JSON.stringify(_.keys(_.pickBy(bindings, function(value, key){ if(typeof jsh.XExt.LiteralOrLookup(value) != 'undefined') return true; return false; })))%>,
    keys:[<% xejs.eachKey(model.fields,function(field){%>'<%=field.name%>',<%});%>],
    commitlevel:'<%=(model.commitlevel?model.commitlevel:'')%>',
    curtab:<%-(curtab?JSON.stringify(curtab):'null')%>,
    tabpos:<%-JSON.stringify(model.tabpos||null)%>,
    hide_system_buttons:<%-(model.hide_system_buttons?JSON.stringify(model.hide_system_buttons):'[]')%>,
    unbound_data: {},
    using: <%-JSON.stringify(model.using)%>,
    <% 
    if('default_search' in model){ %> default_search:<%-JSON.stringify(model.default_search)%>, <% }
    if('oninit' in model){ %> oninit:function(xmodel){<%-jslocals%><%-model.oninit%>}, <% }
    if('onload' in model){ %> onload:function(xmodel, callback){<%-jslocals%><%-model.onload%>}, <% }
    if('onloadimmediate' in model){ %> onloadimmediate:function(xmodel, callback){<%-jslocals%><%-model.onloadimmediate%>}, <% }
    if('oninsert' in model){ %> oninsert:function(xmodel,urlkeys,url){<%-jslocals%><%-model.oninsert%>}, <% }
    if('onupdate' in model){ %> onupdate:function(xmodel){<%-jslocals%><%-model.onupdate%>}, <% }
    if('oncommit' in model){ %> oncommit:function(xmodel,rowid,callback){<%-jslocals%><%-model.oncommit%>}, <% }
    if('onvalidate' in model){ %> onvalidate:function(xmodel, callback){<%-jslocals%><%-model.onvalidate%>}, <% }
    if('ondestroy' in model){ %> ondestroy:function(xmodel){<%-jslocals%><%-model.ondestroy%>}, <% }
    if('onloadstate' in model){ %> onloadstate:function(xmodel, state){<%-jslocals%><%-model.onloadstate%>}, <% }
    if('ongetstate' in model){ %> ongetstate:function(xmodel, state){<%-jslocals%><%-model.ongetstate%>}, <% }
    if('onrowbind' in model){ %> onrowbind:function(xmodel, jobj, datarow){<%-jslocals%><%-model.onrowbind%>}, <% }
    if('onrowunbind' in model){ %> onrowunbind:function(xmodel, jobj, rowid){<%-jslocals%><%-model.onrowunbind%>}, <% }
    if('onchange' in model){ %> onchange:function(obj,newval,e){<%-jslocals%><%-model.onchange%>}, <% }
    if('getapi' in model){ %> getapi:function(apitype){<%-jslocals%><%-model.getapi%>}, <% }

    if(model.unbound){ %> unbound:true, <% }
    if(model.inlinepopup){ %> inlinepopup:true, <% }
    %>

    flags: {
      no_form_record: false
    },
    _sysconfig: <%-JSON.stringify(model._sysconfig)%>
  };
  xmodel.getBindingOrRootKey = function(bindingname){
    if(xmodel.bindings && (bindingname in xmodel.bindings)) return xmodel.bindings[bindingname]();
    if(xmodel.id==jsh.XModels_root){
      if(xmodel.hasBindingOrRootKey(bindingname)) return jsh._GET[bindingname];
    }
    return undefined;
  }
  xmodel.hasBindingOrRootKey = function(bindingname){
    if(xmodel.bindings && (bindingname in xmodel.bindings)) return true;
    if(xmodel.id==jsh.XModels_root){
      if(xmodel.datamodel){
        for(var fieldname in xmodel.fields){
          if(fieldname != bindingname) continue;
          var field = xmodel.fields[fieldname];
          if(field.unbound) continue;
          if((field.key || field.lovkey) && (field.name in jsh._GET)) return true;
        }
      }
    }
    return false;
  }
  xmodel.has = function(fieldname){
    var xform = null;
    if(xmodel.controller && xmodel.controller.form) xform = xmodel.controller.form;
    if(xmodel.hasBindingOrRootKey(fieldname)) return true;
    if(xmodel.fields && xmodel.fields[fieldname]) return true;
    return false;
  }
  xmodel.get = function(fieldname, rowref){
    var xform = null;
    if(xmodel.controller && xmodel.controller.form) xform = xmodel.controller.form;
    if(xmodel.hasBindingOrRootKey(fieldname)) return xmodel.getBindingOrRootKey(fieldname);
    if(xmodel.layout=='grid'){
      //Get rowid from rowref
      var rowid = -1;
      if(typeof rowref == 'undefined'){ XExt.Alert('Rowref parameter is required for model.get(fieldname, rowref) in grid layout'); return; }
      if(_.isNumber(rowref)) rowid = rowref;
      else if(rowref) rowid = jsh.XExt.XModel.GetRowID(modelid, rowref);
      else if(rowref===null) rowid = xmodel.controller.GetRowID();
      
      if((rowid >= 0) && (rowid < xform.DataSet.length)){
        if(xform){
          //If the rowid is being edited
          if(xform.Index == rowid){
            var field = xform.Data.Fields[fieldname];
            var has_field = !!field;
            if(has_field && !XExt.hasAction(field.actions,'IU') && _.includes(['html','label','linkbutton','button'],field.control)) has_field = false;
            if(has_field) return XExt.getFormField(xform, fieldname);
          }
          return xform.DataSet[rowid][fieldname];
        }
      }
      else{ console.log('Invalid row: '+rowid); console.log(rowref); console.trace(); XExt.Alert('Invalid row'); return; }
    }
    if(xform){
      var field = xmodel.fields && xmodel.fields[fieldname];
      var formval = undefined;
      var has_field = !!field;
      if(has_field && !XExt.hasAction(field.actions,'IU') && _.includes(['html','label','linkbutton','button'],field.control)) has_field = false;
      if(has_field) formval = XExt.getFormField(xform, fieldname);
      else if(fieldname in xmodel.controller.form.Data) formval = xmodel.controller.form.Data[fieldname];
      if(jsh.is_insert && field && field.key && XExt.isNullUndefinedEmpty(formval) && !XExt.hasAction(field.actions, 'I')) return undefined;
      return formval;
    }
    XExt.Alert('Could not get value - model.controller.form not initialized');
  }
  xmodel.set = function(fieldname, value, rowref, onComplete){
    var xform = null;
    if(xmodel.controller && xmodel.controller.form) xform = xmodel.controller.form;
    if(xmodel.layout=='grid'){
      //Get rowid from rowref
      var rowid = -1;
      if(typeof rowref == 'undefined'){ XExt.Alert('Rowref parameter is required for model.set(fieldname, value, rowref) in grid layout'); return; }
      if(_.isNumber(rowref)) rowid = rowref;
      else if(rowref) rowid = jsh.XExt.XModel.GetRowID(modelid, rowref);
      else if(rowref===null) rowid = xmodel.controller.GetRowID();

      if((rowid >= 0) && (rowid < xform.DataSet.length)){
        var xeditablegrid = xmodel.controller.editablegrid;
        if(xform){
          //Navigate to the new row
          xmodel.controller.NavTo(rowid, function(){
            //Update data
            XExt.setFormControl(xform, fieldname, value);
            if(onComplete) onComplete();
          });
          return;
        }
      }
      else{ console.log('Invalid row: '+rowid); console.log(rowref); console.trace(); XExt.Alert('Invalid row'); return; }
    }
    if(xform){
      XExt.setFormControl(xform, fieldname, value);
      if(onComplete) onComplete();
    }
    else XExt.Alert('Could not set value - model.controller.form not initialized');
  }
  xmodel.isEnabled = function(){
    if(xmodel.flags.no_form_record) return false;
    if(xmodel.controller && xmodel.controller.form && xmodel.controller.form.Prop && ('Enabled' in xmodel.controller.form.Prop) && !xmodel.controller.form.Prop.Enabled) return false;
    if(xmodel.controller && xmodel.controller.grid && xmodel.controller.grid.Prop && ('Enabled' in xmodel.controller.grid.Prop) && !xmodel.controller.grid.Prop.Enabled) return false;
    return true;
  }
  xmodel.saveUnboundFields = function(row){
    if(!this.fields) return;
    var keys = {};
    var values = {};
    _.each(this.fields, function(field){
      if(field.key) keys[field.name] = row[field.name];
      if(field.unbound && field.name && (field.name in row)) values[field.name] = row[field.name];
    });
    this.unbound_data[JSON.stringify(keys)] = values;
  }
  //loadUnboundFields - Returns true if data is found
  xmodel.loadUnboundFields = function(row){
    if(!this.fields) return;
    //Find keys
    var keys = {};
    var values = {};
    _.each(this.fields, function(field){
      if(field.key) keys[field.name] = row[field.name];
    });
    var keystr = JSON.stringify(keys);
    var unbound_fields = this.unbound_data[keystr];
    if(!unbound_fields) return false;
    _.each(this.fields, function(field){
      if(field.unbound && field.name && (field.name in unbound_fields)) row[field.name] = unbound_fields[field.name];
    });
    return _.keys(unbound_fields);
  }
  if(!(basemodelid in jsh.XBase)) jsh.XBase[basemodelid] = [];
  jsh.XBase[basemodelid].push(modelid);
  <% if('js' in model){ %>
    if(!(modelid in jsh.App)) jsh.App[modelid] = {};
    <%-jsh.RenderEJS(model.js,ejsparams)%>
  <% } %>
  <% if('jslib' in model){ %>
    if(!(modelid in jsh.App)) jsh.App[modelid] = {};
    <%-model.jslib%>
  <% } %>
})(<%-instance%>);
</script>
<% if(('css' in model) && model.css && model.css.trim()){ %>
<style type="text/css">
<%-jsh.RenderEJS(model.css,ejsparams)%>
</style>
<% } %>
<script type="text/javascript">
<%-jsh.RenderView('jsh_'+xejs.case(
  model.layout=='form','form',
  model.layout=='form-m','form',
  model.layout=='multisel','multisel',
  model.layout=='exec','exec',
  model.layout=='report','exec',
  model.layout=='grid','grid'
  )+'.js',ejsparams)%>
</script>