
/**
 * @author Вячеслав
 */

//--------------------------ColumnModel---------------------------------
var columnModel = function(param)
{
    this.model = param;
    this.init();
}

columnModel.prototype.init = function()
{
    for(var i = 0;i < this.model.length; i++){
          if (this.model[i].isSorted == undefined)
              this.model[i].isSorted = true;
  }
}
 
//---------------------------JSONReader---------------------------------
var JSONReader = function(param, fields)
{
    this.fields = fields;
    //param //FIX ME    
    //this.record = new Array();
    this.root = param.root;
    this.totalProperty = param.totalProperty
}

JSONReader.prototype.parseData = function(data)
{    
    var parseData;
    try{
        parseData = eval(data);
    }
    catch(e)
    {
        alert("Ошибка разбора данных\n" + e);
        return false;
    }
    
    return     parseData;
}

JSONReader.prototype.getData = function(obj, callback)
{
  this.obj = obj;
  this.callback = callback;
  this.proxy.load(this, this.putData);
}

//

var ArrayReader = function(param, fields)
{
    this.fields  = fields;
    this.root    = "root";
    
}

ArrayReader.prototype.parseData = function(data)
{        
    if (typeof data == 'string') 
  try{  
    data = eval(data);
  }
  catch(e)
  {
    alert("Ошибка разбора данных.\n" + e );
  }
  
  var arr = new Array();
  for (var j=0;j< data.length; j++)
  {
    var obj = new Object();
    for (var i=0;i< this.fields.length; i++)
    {
      obj[this.fields[i].name] = data[j][i];    
    }
    arr.push(obj)
  }
  var obj = Object();
  obj.root = arr;
  return obj;
}


//--------------------Proxy------------------------------------------------
var Proxy = function(url, method)
{
    this.url       = url;
    this.method = method;
  this.request = new net.ContentLoader(this.url,this.onload,this.onFailure,this);
  this.obj = null;
  this.callbackfunc = null;
}

Proxy.prototype.load = function(baseParams)
{    
  //this.request.abort();
    this.request.baseParams         = baseParams;
    this.request.baseParams.rnd = Math.random(1);
    this.request.loadXMLDoc(this.url);
}


Proxy.prototype.onFailure = function(req, url ,obj)
{
    if (obj.dataStore.onFailure) obj.dataStore.onFailure(req.statusText)
}



Proxy.prototype.onload = function(req)
{
  var text = req.responseText;
  this.dataStore.onload(text);
}

var MemoryProxy = function(array)
{
  this.array = array;
}

MemoryProxy.prototype.load = function(baseParams)
{    
  this.onload();
}

MemoryProxy.prototype.onload = function(req)
{  
    this.dataStore.onload(this.array);    
}


//-------------------------------------------------------------------------

//-------------------DataStore----------------------------------------------



var has_mask = function(obj){
    return obj.mask != 'undefined';
}

var has_unmask = function(obj){
    return obj.unmask != 'undefined';
}

var has_refresh = function(obj){
    return obj.refresh != 'undefined';
}

var default_failure = function(text){
    alert("Произошла ошибка: " + text);
}


var dataStore = function(proxy, reader)
{
    this.proxy      = proxy;
    this.proxy.dataStore = this;      
    this.reader  = reader;
    this.data      = null;
    this.onloadFunctions = new Array();

    //this.page = 1;
    this.count = 25;
    this.start = 0;
    this.limit = 25;
    this.modified = [];
    this.deleted = [];
    this.records  = [];
    this.filters = [];
    this.view = [];
    this.dependenceDS = [];
    this.baseParams;
    this.isLoaded = false;
    
    //modified
    this.modif_id = -1;
}

dataStore.prototype.onError = function()
{
    //alert("Не удалось получить данные");
    map(methodcaller('unmask'), filter(has_unmask, this.view));

}

dataStore.prototype.checkDependence = function(param)
{
    for (var i=0;i<this.dependenceDS.length;i++)
    {
        if (!this.dependenceDS[i].isEmpty())
        {
            this.dependenceDS[i].retryLoad = {func:this.load, obj:this,param:param}; //Fix Name                            
            return true;
        }
    }
        
    return false;
}

dataStore.prototype.load = function(param)
{            
    map(methodcaller('mask'), filter(has_unmask, this.view));

    if(this.beforeload) this.beforeload();  
    if(this.beforeLoad) this.beforeLoad();
    
    if (param)            
    {        
        if (param.start != null)
            this.start = param.start;
        if (param.limit != null)
            this.limit = param.limit; 
    
        if (param.sort) this.sort = param.sort;
        if (param.dir)  this.dir  = param.dir;
    }    
    
        
        
    //var baseParams= {start:this.start,limit:this.limit};
    var baseParams = {};
    if (this.start != null) baseParams.start = this.start;
    if (this.limit != null) baseParams.limit = this.limit;
    if (this.sort) baseParams.sort = this.sort;
    if (this.dir)  baseParams.dir = this.dir;
    

    if (this.baseParams)
    {
        for (var p in this.baseParams)
            baseParams[p] = this.baseParams[p];
    }
    
    //filters
    for (var i=0; i<this.filters.length;i++)
    {
        if (this.filters[i].name)
        {
            var value = this.filters[i].getValue();
            if (String(value) == "" || (typeof value == "boolean" && value == false)) continue;                   //может можно и без этого обойтись,false в случае, если не смогли получить значение
            baseParams[this.filters[i].name] = value;  //
        }  
    }
    this.proxy.load(baseParams);            
}


dataStore.prototype.isEmpty = function()
{    
    if (this.records.length !=0 ) return false;
    return true;
}

dataStore.prototype.onload = function(responseText)
{

  this.isLoaded      = true;
  var data                 = responseText;
  var parseData        = this.reader.parseData(data);
  //следует в будущем создать сласс record
  this.records         = parseData[this.reader.root];
  this.id            = parseData[this.reader.id];
  if (this.onSuccess) this.onSuccess();
  if (this.afterLoad) this.afterLoad(this.records); //FIX 
  this.modified = [];
    
    this.totalCount = parseData[this.reader.totalProperty];

    //CallBack Function
    for (var i=0;i<this.onloadFunctions.length;i++)
    {
        var el = this.onloadFunctions[i];        
        el.func.call(el.obj);
    }

    map(methodcaller('unmask'), filter(has_unmask, this.view));        


    map(methodcaller('refresh'), filter(has_refresh, this.view));    

    if (this.retryLoad)
    {        
        this.retryLoad.func.call(this.retryLoad.obj);
    }                
    this.modif_id++;
    
    //if (this.afterLoad) this.afterLoad(this.records); //FIX 
}

dataStore.prototype.getRecords = function()
{
  return this.records;
}

dataStore.prototype.setValue = function(index, name, value)
{
    if (!this.records[index].modified)
        this.records[index].modified = {};
    if (this.modified.indexOf(this.records[index]) == -1)
        this.modified.push(this.records[index]);
    this.records[index].modified[name] = value;
    this.records[index][name] = value;
     this.records[index].isModifed = true;
}


dataStore.prototype.getModifedRecords = function()
{
  return this.modified;
}

dataStore.prototype.insert = function(position, rec)
{
  this.records.unshift(rec);    
  //this.modified.unshift(rec); //FIX

    map(methodcaller('refresh'), filter(has_refresh, this.view));
    
}

dataStore.prototype.remove = function(rec)
{
    
      var index = this.records.indexOf(rec);  
    if (index == -1) return;
    this.records[index].isDelete = true;
    this.deleted.push(this.records[index]);
    
    map(methodcaller('refresh'), filter(has_refresh, this.view));
    
}

dataStore.prototype.removeAll = function()
{        
    this.records = [];    
    this.modified = [];       
    map(methodcaller('refresh'), filter(has_refresh, this.view));
    
}

dataStore.prototype.getById = function(id)
{
    for(var i=0; i<this.records.length; i++)
    {
       if (this.records[i].id == id) 
           return this.records[i];   
    }
    return false;
}

dataStore.prototype.getNextById = function(id)
{
   for(var i=0; i<this.records.length; i++)
   {
       if (this.records[i].id == id){
           i++;
           if (i >= this.records.length)
               i = 0;
           return this.records[i];
       }
   }
   return false;
}

dataStore.prototype.getPrevById = function(id)
{
   for(var i=0; i<this.records.length; i++)
   {
       if (this.records[i].id == id){
           i--;
           if (i < 0)
               i = this.records.length - 1;
           return this.records[i];
       }
   }
   return false;
}

dataStore.prototype.getCount = function()
{
    return this.records.length;
}

dataStore.prototype.addFilter = function(filter)
{
  this.filters.push(filter);  
}

dataStore.prototype.eraseRemove = function(filter)
{
    for(var i = 0;i < this.records.length; i++)
    {
    if (this.records[i].isDeleted)
    {
                var index = this.records.indexOf(this.records[i]);
                this.records.remove(index);
        }
     }
}

///////// HTTP Reader beta
var HttpReader = function(param, fields){
    this.fields  = fields;
    this.root    = "root";    
}
        
HttpReader.prototype.parseData = function(data){        
    var arr = new Array();
    var preObj = new Object();
    
    preObj['data'] = data;    
    arr.push(preObj)
    var obj = Object();
    obj.root = arr;
    return obj;
}

