var nam_data = {loaded:false,user:{},content_types:[], records:[], tags:[], playlists:[],background:"/static/img/main_background.png"};
nam_data.master_type = new ContentType("All Content");
dataStamp(nam_data.master_type);
nam_data.playlist_type = new ContentType("Playlists");
dataStamp(nam_data.master_type);


function loadData(thefunc) {

    namreq("get","/load_data",
    function(result){
        var data = result.data;
        _.each(data.content_types, function (cType) {
            var conType = nam_merge(new ContentType(cType.name),cType);
            var lister = new Playlist(conType.name, conType._id);
            lister.isContentList = true;
            nam_data.content_types.push(conType); 
            nam_data.playlists.push(lister);

        });
        _.each(data.playlists, function (pList) {
            var p = new Playlist(pList.name, null);
            nam_data.playlists.push(nam_merge(p,pList));
            p.loaded = false;
        });
        _.each(data.records, function (record) {
            var rec = nam_merge(new Record(null), record);
	    nam_data.records.push(rec);
        });
         
        nam_data.tags = data.tags; 
        nam_data.content_list = buildContentTypesList();
        nam_data.playlist_list = buildPlaylistsList();
        nam_data.playlists.push(nam_data.content_list);
        nam_data.playlists.push(nam_data.playlist_list); 
        nam_data.loaded = true; 
        if (thefunc != undefined) {
            thefunc();
        }
    });
}
function nam_merge(obj1, obj2) {
    for (attrname in obj2) { 
        if (typeof obj2[attrname] != "function") {    
            obj1[attrname] = obj2[attrname]; 
        }
    }
    return obj1;
}
function buildContentTypesList() {
    var master_type = nam_data.master_type; 
    var list = new Playlist("content",master_type._id);
    var titleCol = new master_type.Column("Title", "text");
    list.content_type_id = master_type._id;
    _.each(nam_data.content_types, function(conType){
        var name = conType.name;
        var record = createRecord(list);
        record.setFieldValue(titleCol, name);
    });
    dataStamp(list);
    return list;
}
function buildPlaylistsList() {
    var playlist_type = nam_data.playlist_type; 
    var list = new Playlist("playlists",playlist_type);
    list.isPlaylistList = true;
    list.content_type_id = playlist_type._id;
    var titleCol = new playlist_type.Column("Title", "text");
    var typeCol = new playlist_type.Column("Type", "text");

    _.each(nam_data.playlists, function(playlist){
        if (playlist.isContentList == false && playlist.getContentType() != nam_data.master_type) {
            var record = createRecord(list);
            record.setFieldValue(titleCol, playlist.name);
            record.setFieldValue(typeCol, playlist.getContentType().name);
        }
    });

    dataStamp(list);
    return list;
}

function dataStamp(data, id) {
    if (id == undefined) {
        id = getId();
    }
    var now = new Date().getTime();
    if (data._id == undefined) {
        data._id = id;
        data.created_at = now;
    }
    data.updated_at = now;
}
function getId() {
    return guid();
}
function S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
   return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
function Playlist(name, contentTypeIder) {
    var self = this;
    var table = null;
    this.path = lower_score(name);
    this.isContentList = false;
    this.isPlaylistList = false;
    this.loaded = false;
    this.collection = "playlists";
    this.content_type_id = contentTypeIder;
    this.name = name;
    this.default_col = null;
    this.x = 0;
    this.y = 0;
    this.records = [];
    this.public = false;
    this.setTable = function(tab) {
        table = tab;
    }
    this.table = function() {
        return table;
    }
    this.setBackground = function(rec) {
        //get image content, displayed as thumbs
        self.background = rec._id;
        nam_save(self);
    }
    this.currentRecord = function() {
        return self.getRecord(self.y);
    }
    this.currentColumn = function() {
        return self.getContentType().columns[self.x];
    }
    this.nextColumn = function() {
        self.x += 1;
        if (self.x >= self.getContentType().columns.length) self.x = 0;
        return self.currentColumn();
    }
    this.prevColumn = function() {
        self.x -= 1;
        if (self.x < 0) x = self.getContentType().columns.length-1;
        return self.currentColumn();
    }
    this.nextRecord = function() {
        self.y = self.y+1;
        if (self.y >= self.getRecordsLength()) self.y = 0;
        log("self.nextRecord, length:"+self.getRecordsLength(),self.y);
        return self.currentRecord();
    }
    this.prevRecord = function() {
        self.y -= 1;
        if (self.y < 0) self.y = this.getRecordsLength()-1;
        log("self.nextRecord, length:"+self.getRecordsLength(),self.y);

        return self.currentRecord();
    }
    this.getRecord = function(index) {
        var record = null;
        if (self.isContentList) {
            if (this.content_recs == undefined) {
                this.content_recs = _.select(nam_data.records, function(rec) { return rec.content_type_id == self.content_type_id;});
            }
            record = this.content_recs[index];
        }
        else {
            var rec_id = self.records[index];
            var record = getRecordById(rec_id);
        }
        return record;
    }
    this.getRecordsLength = function() {
        var length = 0;
        if (self.isContentList) {
            var content_recs = _.select(nam_data.records, function(rec) { return rec.content_type_id == self.content_type_id;});
            length = content_recs.length;
        }
        else {
            length = self.records.length;
        }
        return length;
    }
    this.getContentType = function() {
        var type = null;
        if (self.content_type_id == nam_data.master_type._id) {
            type =  nam_data.master_type;
        }
        else if (self.content_type_id == nam_data.playlist_type._id) {
            type = nam_data.playlist_type; 
        }
        else {
            type = getContentTypeById(self.content_type_id);
        }
        return type;
    }
    this.currentFieldContentPath = function() {
        return self.getFieldContentPath(self.currentColumn());
    }
    this.getFieldContentPath = function(column) {
        var value = self.currentRecord().getFieldValue(column);
        var path = "/file/"+self.currentRecord()._id+"/"+column._id+"/"+value; 
        //alert(path);
        return path;
    }
    this.currentField = function() {
        var rec = self.currentRecord();
        var col = self.currentColumn();
        var field = rec.getFieldByColumn(col,true); 
        return field;
    }
    this.getDefaultColumn = function() {
        var col = null;
        if (self.default_col != null) {
            col = self.getContentType().getColumnById(self.defaul_col);
        }else {
            col = _.detect(self.getContentType().columns, function(col) {
                return col.type == self.getContentType().name.toLowerCase();
            });
        }
        return col;
    }
}
function Tag(name) {
    this.collection = "tags";
    this.name = name;
}
function ContentType(name) {
    var thiz = this;
    this.collection = "content_types";
    this.name = name;
    this.columns = [];

    this.Column = function(colName, type) {
        this._id = thiz.columns.length;
        this.name = colName.toLowerCase();
        this.type = type;
        thiz.columns.push(this);
        return this;
    }
    this.getColumnById = function(id) {
        return _.detect(thiz.columns, function(col) { return col._id == id;});
    }
}
function Record(content_type_id) {
    var Rec = this;
    this.collection = "records";
    this.content_type_id = content_type_id;
    this.fields = [];
    this.tags = [];
    this.playlists = [];
    this.Field = function (column, value) {
        this._id = Rec.fields.length;
	this.type = column.type;
	this.column_id = column._id;
	this.record_id = Rec._id;
	Rec.fields.push(this);
        return this;
    }
    this.setFieldValue = function(column, val) {
        //log("setFieldValue: "+val);
        var field = Rec.getFieldByColumn(column,true);
        var val = Rec.handleFieldValue(column, val);
        field.value = val;
        return val;
    }
    this.handleFieldValue = function (column, val) {
	if (column.type == "date") {
	    val = Date.parse(val).getTime();
	}
	return val;
    }
    this.getFieldByColumn = function (column, create) {
	var field = _.detect(Rec.fields,function(f){return f.column_id == column._id;});
        if (field == undefined && create) {
            field = new Rec.Field(column);
        }
	return field;
    }
    this.getFieldValue = function(column) {
	var fieldValue = "";
	var field = Rec.getFieldByColumn(column, false);
        if (field != undefined) {
	    if (column.type == "date") {
		fieldValue = new Date(field.value).toString("ddd, MMM dd h:mm");
	    }else {
		fieldValue = field.value;
	    }
        }
	return fieldValue;
    }
    this.getFieldContentPath = function(col_name) {
       var c_type = Rec.getContentType();
       var col = getColumnByType(c_type, col_name);
       var val = Rec.getFieldValue(col);
       var path = "/file/"+Rec._id+"/"+col._id+"/"+val; 
       return path; 
    }
    this.getContentType = function() {
        var type = null;
        if (Rec.content_type_id == nam_data.master_type._id) {
            type =  nam_data.master_type;
        }
        else if (Rec.content_type_id == nam_data.playlist_type._id) {
            type = nam_data.playlist_type; 
        }
        else {
            type = getContentTypeById(Rec.content_type_id);
        }
        return type;
    }
}

function createRecord(playlist) {
   var record = new Record(playlist.getContentType()._id);
   dataStamp(record); 
   record.playlists.push(playlist._id);
   playlist.records.push(record._id);
   nam_data.records.push(record);
   playlist.content_recs = undefined;
   return record;
}


function getContentTypeById(contentTypeId) {
   var c_type = _.detect(nam_data.content_types, function(type) {return type._id = contentTypeId;});
   return 
}
function getContentTypeByName(name) {
  return _.detect(nam_data.content_types, function(list) {return list.name == name;}); 
}
function getColumnByName(contentType, name) {
  return _.detect(contentType.columns, function(column) {return column.name == name;}); 
}
function getColumnByType(contentType, columnType) {
  return _.detect(contentType.columns, function(column) {return column.type == columnType;}); 
}

function updateField(value) {
    var rec = currentList.currentRecord();
    if (rec == undefined) {
        rec = createRecord(currentList);
    }
    var col = currentList.currentColumn();
    rec.setFieldValue(col, value);
    nam_save(rec);
    if (!currentList.isContentList && currentList.getContentType() != nam_data.master_type && currentList.getContentType() != nam_data.playlist_type ) {
      var match = _.detect(currentList.records, function(rec_id) {
          return rec_id == rec._id;
      });
      if (match != undefined) {
          log("save playlist");
          nam_save(currentList);
      }
    }

    return rec.getFieldValue(col);
}

function addColumn(name, colType) {
    log("addColumn");
    var contentType = currentList.getContentType();
    log("addColumn: conType",contentType);
    new contentType.Column(name, colType);
    log("addColumn: col created");
    currentList.refresh();
    log("saving",contentType.name);
    nam_save(contentType);
}
function removeCurrentColumn() {
    currentList.contentType.columns = removeById(currentList.contentType.columns,currentList.currentColumn()._id);
}
function removeSelectedData() {
     var data = null;
     if (currentList == nam_data.content_list || currentList == nam_data.playlist_list) {
     }
     else {
        data = currentList.currentRecord();       
	if (currentList.isContentList) {
	     nam_data[data.collection] = removeById(nam_data[data.collection], data._id);
	     nam_delete(data);
	     var playlist_ids = data.playlists;
	     _.each(playlist_ids, function (pid) {
		 var playlist = getById(nam_data.playlists, pid);
		 playlist.records = removeById(playlist.records, data._id); 
		 nam_save(playlist);
	     });
	     currentList.content_recs = undefined;
	 }
	 else {
	     currentList.records =  removeValue(currentList.records, data._id);
	     data.playlists = removeValue(data.playlists, currentList._id);
	     nam_save(currentList);
	     nam_save(data);
	 } 
     }

     refreshList();
}

function getById(arr, id) {
    return _.detect(arr, function(item) {
        return item._id == id;
    });
}
function removeById(arr, id) {
    return _.reject(arr, function(item) {
        return item._id == id;
    });   
}
function removeValue(arr, val) {
    return _.reject(arr, function(item) {
        return item == val;
    });   
}
function getRecordById(id,func) {
   var rec = getById(nam_data.records, id);
   return rec; 
}
function getPlaylistById(id) {
    return getById(nam_data.playlists, id);
}
function getPlaylistByName(name) {
    log("getPlaylistByName:",name);
    if (name == null || name == undefined || name.trim() == "") {
        if (nam_data.email) {
            name = "content";
        } else {
            name = "playlists";
        }
    }
    return _.detect(nam_data.playlists, function(p) { return p.name == name;});
}
function getPlaylistByPath(path) {
    log("getPlaylistByPath: "+path);
    return _.detect(nam_data.playlists, function(p) { return p.path == path;});
}
function getContentTypeById(id) {
    return getById(nam_data.content_types, id);
}


function nam_save(data,func) {
    if (!nam_auth()) return;
    if (data.isContentList == true || data == nam_data.content_list || data == nam_data.playlist_list) { 
        log("WOAH!!  This shouldn't be saving");
        return;
    }
    if (data.collection == "playlists") {
        data.content_recs = undefined;
    }
    dataStamp(data);
    log("save: "+JSON.stringify(data));
    namreq("post","/save",function(result_data) {},{collection:data.collection, data:JSON.stringify(data)});
}
function nam_delete(data) {
    if (!nam_auth()) return;
    namreq("post", "/remove",function(data) {},{id:data._id, collection:data.collection});
}
