/**
 * Trim Path Table v. 0.0001
 * Very basic, and mostly incomplete, way to use Trimpath with jQuery to search tables
  */
(function($) {
    //build an anonymous tqTable class
	$.extend({
		tpTable: new function() {

            var columnDefs = {}, tableData = {}, queryLang, whereClause = {}, orderClause = {}, defaultOrder = '';

            /* Draw utiltities */
            function filterTable(table,newWhere,newOrder) {
                table = $(table);
                table.each(function() {
                    //Create Select clause
                    var searchStatment;
                    var sql = "SELECT "+ this.id + ".* FROM " + this.id;

                    //Create where clause
                    var where = (newWhere == null) ? whereClause[this.id] :  newWhere;
                    if (where) sql += " WHERE " + where;

                    //Create Order clause
                    var order = newOrder || orderClause[this.id];
                    if (order) {
                        sql += " ORDER BY " + order;
                        if (order.indexOf(defaultOrder) < 0) {
                            sql += ", " + defaultOrder;
                        }
                    }
                    else {
                        //sql += " ORDER BY " + defaultOrder;
                    }

                    try {
                        searchStatment = queryLang.parseSQL(sql);
                    } catch(e) {
                        alert(sql + " " + e);
                    }
                    if (searchStatment) {
                        var results = searchStatment.filter(tableData);
                        drawTable(this,results);
                    }
                    orderClause[this.id] = newOrder;
                    whereClause[this.id] = newWhere;
                });
            };

            /* Search form utiltities */
            function instrumentSearchForm(forms,table) {
                forms.submit(createWhereClause).submit(function() {
                    return false; //createWhereClause.call(this);
                });
                
                forms.each(function() {
                    this.searchTable = table;
                });

                for (var r in columnDefs) {
                    for (var i in columnDefs[r]) {
                        forms.find("." + r + "." + i).change(changeCriteria);
                    }
                }
            }

            function changeCriteria() {
                $(this).parents("form").submit();
            }

            function createWhereClause() {
                var sql = "";
                var form = $(this);
                for (var r in columnDefs) {
                    for (var i in columnDefs[r]) {
                        var fields = form.find("." + r + "." + i);
                        fields.each(function() {
                            var field = $(this);
                            var value = field.val();
                            if (value) {
                                if (value.indexOf(",") >-1) {
                                    var list = value.split(',');
                                    var innerSql = " (";
                                    for (var q in list) {
                                        var orExpression = list[q];
                                        if (orExpression.trim) orExpression = orExpression.trim();
                                        else {
                                            orExpression = orExpression.replace(/$ */,"");
                                            orExpression = orExpression.replace(/^ */,"");
                                        }
                                        if (q > 0) innerSql += " OR ";
                                        innerSql += singleFieldWhereClause(r,i,orExpression,field.is(".wild"), false);
                                    }
                                    innerSql += ") ";
                                    if (sql.length>0) sql +=" AND ";
                                    sql += innerSql;
                                } else {
                                    sql += singleFieldWhereClause(r,i,value,field.is(".wild"), sql.length > 0);
                                }
                            }
                        });
                    }
                }
                try {
                    filterTable($("#"+this.searchTable), sql, null);
                } catch(e) {
                    alert("filter: " + e + ' sql: "' + sql + '"');
                }
            }

            function singleFieldWhereClause(table,field,value,wild,append) {
                var sql = "";
                var wildcard = (value.indexOf("%") >-1) || (value.indexOf("*") >-1);
                if (wild && !wildcard) {
                    value += "*";
                    wildcard = true;
                }
                if (append) sql += " AND ";
                value = value.replace(" ",".");
                sql += table + "." + field + ((wildcard) ? " LIKE " : " = ") + "'" + value + "'";
                return sql;
            }

            /* Table runtime utiltities */
            function changeOrder() {
                var table = $(this).parents("table");
                var tableId = table.get(0).id;
                var order = " ASC";
                if (orderClause[tableId] && orderClause[tableId].indexOf(tableId+"."+this.id+order) >-1) order = " DESC";
                filterTable(table,whereClause[tableId],tableId + "." + this.id + order);
            }

            function drawTable(table,results) {
                var id = table.id;
                var columns = columnDefs[id];

                var tBody = $(table).children("tbody");
                tBody.empty();

                var alt = "";
                var newBody = "";
                for (i in results) {
                    var newTr = "<tr class='"+ alt +"'>";
                    for (r in columns) {
                        var val = results[i][r];
                        if (columns[r].email) {
                            val = val.replace("~","@");
                            if (columns[r].icon) {
                                val = "<a href='mailto://"+ val + "'>"+"<img title='senda tölvupóst til "+ val +"' src='/thema/vis2009/images/icons/jaicon_externallink.png' />"+"</a>";
                            } else if (columns[r].image) {
                               //do nothing more.
                                alert("smu1");
                            } else {
                                val = "<a href='mailto://"+ val + "'>" + val + "</a>";
                            }
                        } if (columns[r].web) {
                            if (val && val.trim().length > 0) {
                                if (val.indexOf("http://") != 0) val = "http://" + val;
                                var img = "<img title='Tengill á vef fyrirtækisins' src='/thema/vis2009/images/icons/jaicon_externallink.png'/>";
                                if (columns[r].map) img = "<img title='Tengill á kort sem sýnir staðsetningu' src='/thema/vis2009/images/icons/jaicon_map2.png'/>";
                                if (columns[r].info) img = "<img title='Tengill á já.is sem sýnir nánari upplýsingar' src='/thema/vis2009/images/icons/jaicon_info.png'/>";
                                val = "<a title='"+ val +"' target='_new' href='"+ val + "'>"+img+"</a>";
                            } else {
                                val = "";
                            }
                        } if (columns[r].details) {
                            val = "<a class='details' href='#details-"+id+"' rel='overlay'>"+ val +"</a>";
                        }
                        var attr = "";
                        if (columns[r].hidden) attr = "style='display:none' ";
                        if (columns[r].nowrap) attr += "nowrap='nowrap' ";
                        newTr += "<td "+ attr +">" + val + "</td>";
                    }
                    newTr += "</tr>";
                    newBody += newTr;
                    alt = (i%2 != 0) ? "" : "alt";
                }
                tBody.html(newBody);
                if ($.facebox) {
                    var detailTriggers = tBody.find(".details");
                    detailTriggers.click(updateDiv);
                    detailTriggers.facebox(fbset);
                }
            }

            function updateDiv() {
                var item = $(this);
                var id = item.parents("table").get(0).id;
                var detailsDiv = $("#details-" + id);
                if (detailsDiv) {
                    var cnt = 0;
                    for (var i in columnDefs[id]) {
                        detailsDiv.find("#D-"+i).html(item.parents("tr").children("td").eq(cnt).html());
                        cnt ++;
                    }
                }
            }

			/* Table data and drawing utiltities */
            function getTableData(parent, columns) {
                var table = jQuery(parent);
                var rows = table.children("tbody").eq(0).children("tr");
                var length = rows.length;
                var data = [];
                for (var i = 0; i < length; i++) {
                    var rowData = {};
                    var fields = rows.eq(i).children("td");
                    for (r in columns) {
                        var containsHTML = (fields.eq(columns[r].col).children().length > 0);
                        if (containsHTML) rowData[r] = fields.eq(columns[r].col).html();
                        else rowData[r] = fields.eq(columns[r].col).text();
                    }
                    data.push(rowData);
                }
                return data;
            }

            function createColumnDefs(table) {
                var defenition = {};
                var target = jQuery(table);
                var fields = target.children("thead").eq(0).find("th,td");

                var counter = 0;
                fields.each(function() {
                    //Type
                    var field = $(this);
                    var type = {type:"string", col: counter};
                    if (field.is(".number")) type["type"] = "number";

                    //Extra known attributes
                    if (field.is(".email")) type['email'] = true;
                    if (field.is(".icon")) type['icon'] = true;
                    if (field.is(".web")) type['web'] = true;
                    if (field.is(".map")) type['map'] = true;
                    if (field.is(".info")) type['info'] = true;
                    if (field.is(".logo")) type["logo"] = true;
                    if (field.is(".details")) type["details"] = true;
                    if (field.is(":hidden") || field.is(".hidden")) type['hidden'] = true;
                    if (field.attr("nowrap") != null) {
                        if (field.attr("nowrap") != false) type['nowrap'] = true;
                    }

                    var defID = this.id || "" + counter;
                    defenition[defID] = type;
                    counter ++;
                });
                fields.click(changeOrder);
                fields.css("cursor","hand");
                return defenition;
            }

			/* public methods */
			this.construct = function(form, defOrder) {
                defaultOrder = defOrder;
                if (!TrimPath) {
                    //alert("Trimpath is missing");
                    return;
                }
                this.each(function() {
                    if (this.id) {
                        columnDefs[this.id] = createColumnDefs(this);
                        tableData[this.id] = getTableData(this, columnDefs[this.id]);
                        instrumentSearchForm(form,this.id);
                    }
                });
                queryLang = TrimPath.makeQueryLang(columnDefs);
			};

		}
	});

	// extend into plugin scope
	$.fn.extend({
        tpTable: $.tpTable.construct
	});

    /** If I need to instrument the class
	var tqt = $.tqTables;

	// add default parsers
	tqt.addParser({id: "text"});
    **/

})(jQuery);
