function Eform()
{this.models=new Object();this.views=new Object();this.formatter=new EformFormatter();this.evaluator=new EformExpressionEvaluator();this.evaluator.setVariables(this.models);this.runtime=new EformRuntime();this.runtime.evaluator=this.evaluator;this.addModel=function(model)
{this.models[model.name]=model;if(model.setSelfcheck)
model.setSelfcheck(this.runtime,this.runtime.update,[model]);}
this.addView=function(view)
{this.views[view.id]=view;if(view.type=="Button"||view.type=="ButtonNext"||view.type=="ButtonBack")
{view.addOnClick(this,this.updateView,[view.id]);}}
this.getPage=function()
{for(var v in this.views){if(this.views[v].type=="Page"){return this.views[v];}}
return null;}
this.addModelListener=function(object,method)
{for(var m in this.models)
{if(this.models[m].addOnChange){this.models[m].addOnChange(object,method,[]);}}}
this.addModelDependency=function(source,target)
{var modelSource=this.models[source];var modelTarget=this.models[target];if(modelSource==null||modelTarget==null)throw(this+" empty source ("+source+") or target ("+target+") in dependency declaration");modelSource.addOnChange(this,this.updateModel,[modelTarget.name]);}
this.addModelDependencies=function(dependencies)
{for(var i=0;i<dependencies.length;i++)
{var source=dependencies[i][0];var target=dependencies[i][1];this.addModelDependency(source,target);}}
this.addViewDependency=function(source,target)
{var model=this.models[source];var view=this.views[target];if(model==null||view==null)throw(this+" empty source ("+source+") or target("+target+") in dependency declaration");model.addOnChange(this,this.updateView,[view.id]);}
this.addViewDependencies=function(dependencies)
{for(var i=0;i<dependencies.length;i++)
{var source=dependencies[i][0];var target=dependencies[i][1];this.addViewDependency(source,target);}}
this.addConnection=function(modelId,viewId)
{var model=this.models[modelId];var view=this.views[viewId];if(model==null||view==null)throw(this+" empty source or target in connection declaration");view.setModel(model);}
this.addConnections=function(connections)
{for(var i=0;i<connections.length;i++)
{var modelId=connections[i][0];var viewId=connections[i][1];this.addConnection(modelId,viewId);}}
this.updateView=function(viewId)
{this.runtime.update(this.views[viewId]);}
this.updateModel=function(modelId)
{this.runtime.update(this.models[modelId]);this.models[modelId].validate();}
this.toString=function()
{return"[eform]";}}
