var	filterLog = log4javascript.getLogger("MappingFilter");
filterLog.setLevel(log4javascript.Level.ERROR);

var filterXMLReq = null;
var getFilterUpdatesMap = true;

function initFilterLogging(appender, level) {
    // Should add failure logic
    if (level != null) {
        filterLog.setLevel(level);
    }
    if (appender == null) {
        appender = new log4javascript.AlertAppender();
    }
    filterLog.addAppender(appender);
}

function clearFilters(updateMap) {
    var filterValues = "";
    var filterForms = document.getElementsByName('filterForm');
    for (var i = 0; i < filterForms.length; i++) {
        var filterForm = filterForms[i];
        if (filterForm) {
            clearFormValues(filterForm);
            filterValues += getFormValues(filterForm);
            filterValues += "&";
        }
    }
    if (updateMap != null) {
        clearFilterServer(filterValues,updateMap);
    } else {
        clearFilterServer(filterValues,true);
    }
}


//function clearFilters(updateMap) {
//    var filterValues = "";
//    var filterForm = document.getElementById('filterForm');
//    if (filterForm) {
//        clearFormValues(filterForm);
//        filterValues += getFormValues(filterForm);
//        filterValues += "&";
//    }
//    filterForm = document.getElementById('defaultFilterForm');
//    if (filterForm) {
//        clearFormValues(filterForm);
//        filterForm.defaultFilter.value='';
//        filterValues += getFormValues(filterForm);
//    }
//    if (updateMap) {
//        clearFilterServer(filterValues,updateMap);
//    } else {
//        clearFilterServer(filterValues,true);
//    }
//}

function applyFilters() {
    var filterValues = "";
    var filterForms = document.getElementsByName('filterForm');
    for (var i = 0; i < filterForms.length; i++) {
        var filterForm = filterForms[i];
        if (filterForm) {
            filterValues += getFormValues(filterForm);
            filterValues += "&";
        }
    }
    sendFilters(filterValues,true);
}


function applyFilter(f)
{
    if (f) {
        sendFilters(getFormValues(f),true);
    }
}

function updateFilterDisplay() {
    var filterValues = "";
    var filterForms = document.getElementsByName('filterForm');
    for (var i = 0; i < filterForms.length; i++) {
        var filterForm = filterForms[i];
        if (filterForm) {
            filterValues += getFormValues(filterForm);
            filterValues += "&";
        }
    }
    sendFilters(filterValues,false);
}

function sendFilters(filterValues,updateMap)
{
   var file = '/pbostation/Filter'
   //var str = getFormValues(f,"validate");
   var str = filterValues + "&returnFilters=true";
   filterLog.debug("applyFilter: " + str);
   xmlReq = getXML(file,str,updateMap);
}

function clearFilter(f)
{
   filterLog.trace("About to clear form");
   //clearFormValues(f);
   f.reset();
   var filterValues = getFormValues(f);
   clearFilterServer(filterValues,true);
}

function clearFilterServer(filterValues,updateMap) {
   var file = '/pbostation/Filter'
   filterLog.trace("Getting cleared form values");
   var str = filterValues + "&clear=true&request=filter";
   filterLog.debug("clearFilter: " + str);
   filterLog.trace("Sending cleared form values");
   xmlReq = getXML(file,str,updateMap);
}

// function getXML(file,str)
// {
    // filterLog.info("getXML: initiating.");
   // var doc = null;
   // if (typeof window.ActiveXObject != 'undefined' )
   // {
       // doc = new ActiveXObject("Microsoft.XMLHTTP");
       // doc.onreadystatechange = update;
   // }
   // else
   // {
       // doc = new XMLHttpRequest();
       // doc.onreadystatechange = update;
   // }
   // doc.open( "POST", file, true );
   // doc.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
   // filterLog.info("getXML: sending.");
   // doc.send(str);
   // showLoading();
   // return doc;
// }

function getXML(file,str,updateMap) 
{
    //if (filterXMLReq) {
    //    alert("Ingoring duplicate request.");
    //    return;
    //}
    showLoading();
	//filterXMLReq = createXMLHttpRequest();
    filterXMLReq = new XMLRequestWrapper();
    filterXMLReq.createXMLHttpRequest();
    var req = filterXMLReq.getReq();
	if(req) {
        getFilterUpdatesMap = updateMap;
        filterLog.debug("getXML: getFilterUpdatesMap: " + getFilterUpdatesMap);
		req.onreadystatechange = filterUpdateCallback;
        // Would be nice to have this async, but...  if (updateMap) {
        if (false) {
            // Do async since we are responsible for updating the map
            req.open("POST", file, true);
            req.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            req.send(str);
        } else {
            // Do sync so that anyone that might be waiting on us to update
            // blocks.
            req.open("POST", file, false);
            req.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            req.send(str);
            processUpdateResponse();
        }
	} else {
        filterLog.error("getXML: Unable to create xml request object.");
    }
}

function filterUpdateCallback() {
    if(filterXMLReq.checkReadyState()) { 
        filterLog.debug("filterUpdateCallback: " + filterXMLReq.getReq().responseText);
        processUpdateResponse();
    }
}

function processUpdateResponse() {
    filterLog.debug("filterUpdateCallback: getFilterUpdatesMap: " + getFilterUpdatesMap);
    updateFormValues(filterXMLReq.getReq().responseText);
    filterLog.debug("filterUpdateCallback: getFilterUpdatesMap(postUpdateForm): " + getFilterUpdatesMap);
    if (getFilterUpdatesMap) {
        updateLayers(lastPointLayer,'same');
    }
    hideLoading(); 
}


// function checkReadyState() { 
    // if (xmlReq!=null){ 
        // if (xmlReq.readyState == 4) { 
            // if (xmlReq.status == 200) { 
                // filterLog.debug("checkReadyState: Successful response");
                // xmlReq = null;
                // return true; 
            // } else { 
                // // Warn the user? 
                // filterLog.error("checkReadyState: Failure status code " + xmlReq.status);
                // //alert("problem receiving data"); 
            // } 
        // } 
    // } else {
        // filterLog.warn("checkReadyState: Unexpected null xmlReq!");
    // }
// }

function getFormValues(fobj,valFunc)
{
   var str = "";
   var val = "";
   var cmd = "";
   for(var i = 0;i < fobj.elements.length;i++)
   {
       //alert(fobj.elements[i].name + ":" + fobj.elements[i].type);
       switch(fobj.elements[i].type)
       {
           case "text":
           case "hidden":
                if(valFunc)
                {
                    //use single quotes for argument so that the value of
                    //fobj.elements[i].value is treated as a string not a literal
                    cmd = valFunc + "(" + 'fobj.elements[i].value' + ")";
                    val = eval(cmd)
                }
                str += fobj.elements[i].name + "=";
                // Yeah i.e. thanks for the not-null "null" which appearantly means null.
                // Hope our users didn't actually want to search for the string "null"
                if (fobj.elements[i].value && "null" != fobj.elements[i].value.toLowerCase()) {
                    str += escape(fobj.elements[i].value);
                }
                str += "&";
                filterLog.trace("getFormValues: Adding " + fobj.elements[i].value);
                break;
           case "select-one":
                str += fobj.elements[i].name +
                "=" + fobj.elements[i].options[fobj.elements[i].selectedIndex].value + "&";
                break;
           case "select-multiple":
                var foundOne = false;
                for (var j = 0; j < fobj.elements[i].options.length; j++) {
                    if (fobj.elements[i].options[j].selected) {
                        foundOne = true;
                        str += fobj.elements[i].name +
                               "=" + fobj.elements[i].options[j].value + "&";
                    }
                }
                if (!foundOne) {
                    str += fobj.elements[i].name + "=&";
                }
                break;
       }
   }
   str = str.substr(0,(str.length - 1));
   filterLog.debug("getFormValues: formValues " + str);
   return str;
}

function clearFormValues(fobj)
{
   filterLog.trace("clearFormValues: entered.");
   for(var i = 0;i < fobj.elements.length;i++)
   {
       //alert(fobj.elements[i].name + ":" + fobj.elements[i].type);
       switch(fobj.elements[i].type)
       {
           case "text":
                filterLog.trace("clearFormValues: Clearing text " + fobj.elements[i].name);
                fobj.elements[i].value = null;
                break;
           case "select-one":
           case "select-multiple":
                filterLog.trace("clearFormValues: Clearing select " + fobj.elements[i].name);
                for (var j = 0; j < fobj.elements[i].options.length; j++) {
                    fobj.elements[i].options[j].selected = false;
                }
                break;
       }
   }
}

function updateFormValues(kvpStr)
{
    if (kvpStr) {
        var lines = kvpStr.split("\n");
        for (var i = 0; i < lines.length; i++) {
            if (lines[i].length > 0) {
                filterLog.trace("updateFormValues: considering line " + lines[i]);
                var kvp = lines[i].split(":");
                if (kvp.length == 2) {
                    filterLog.trace("updateFormValues: found kvp " + kvp);
                    var elem = document.getElementById(kvp[0]);
                    //filterLog.debug("updateFormValues: found elem for " + kvp[0] + ":" + elem);                    
                    if (elem && elem.type) {
                        filterLog.trace("updateFormValues: found elem for " + kvp[0] + ":" + elem + " t:" + elem.type);                    
                        var values = kvp[1].split(",");
                        switch(elem.type) {
                            case "text":
                            case "hidden":
                                if (values.length < 1) {
                                    elem.value = "";
                                    filterLog.trace("updateFormValues: clearing text/hidden " + kvp[0]);
                                } else {
                                    elem.value = values[0];
                                    if (values.length > 1) {
                                        filterLog.trace("updateFormValues: setting text/hidden " + kvp[0]);
                                    } else {
                                        filterLog.warn("updateFormValues: setting text/hidden " + kvp[0] + " to " + values[0] + " first of " + values.length);
                                    }
                                }
                                break;
                            case "select-one":
                                for (var k = 0; k < elem.options.length; k++) {
                                    elem.options[k].selected = false;
                                }
                                if (values.length > 0) {
                                    if (values.length > 1) {
                                        filterLog.warn("updateFormValues: select-one " + kvp[0] + ", more than one value only using " + values[0] + ", first of " + values.length);
                                    }
                                    for (var j = 0; j < elem.options.length; j++) {
                                        for (var k = 0; k < 1; k++) {
                                            if (areEqual(elem.options[j].value,values[k],true)) {
                                                elem.options[k].selected = true;
                                                filterLog.trace("updateFormValues: selecting select-one " + kvp[0] + " to " + values[k]);
                                            }
                                        }
                                    }
                                }
                                break;
                            case "select-multiple":
                                for (var k = 0; k < elem.options.length; k++) {
                                    elem.options[k].selected = false;
                                }
                                filterLog.trace("updateFormValues: reset values for select-multiple " + kvp[0]);
                                filterLog.trace("updateFormValues: values " + values.length + " elem.options " + elem.options.length);
                                if (values.length > 0) {
                                    for (var j = 0; j < elem.options.length; j++) {
                                        for (var k = 0; k < values.length; k++) {
                                            filterLog.debug("updateFormValues: comparing " + elem.options[j].value + "==" + values[k]);
                                            if (areEqual(elem.options[j].value,values[k],true)) {
                                                elem.options[j].selected = true;
                                                filterLog.trace("updateFormValues: selecting select-multiple " + kvp[0] + " to " + values[k]);
                                            }
                                        }
                                    }
                                }
                                break;
                        }
                    }
                } else {
                    filterLog.warn("Unknown kvp: " + lines[i]);
                }
            }
        }
    }
    
    function areEqual(a, b, upper) {
        var valuesEqual = (a == b);
        if (!valuesEqual && upper) {
            try {
                valuesEqual = (a.toUpperCase() == b.toUpperCase());
            } catch(e) {
                //Intentional no-op
            }
        } else {
        }
        return valuesEqual;
    }
}

