/**
 * Uhul class object, global object for necessary variables
 * @constructor
 */
var uhul = function() {}; 
var hsLayers = null;


/**
 * Initializes OpenLayers.Map object
 * 
 */
function initMap() {

    hsLayers = new HSLayers();
    /*
     * Map initialization
     * EPSG:102067
     */
    OpenLayers.ProxyHost = "/cgi-bin/olproxy.cgi?url=";

    var options = HSLayers.getProjectionOptions("epsg:102067",2000000,2000);

    // ovladaci prvky v mape udelame vlastni
    options.controls = [];

    uhul.map = new OpenLayers.Map("map",options);
    uhul.map = uhul.map;
    hsLayers.setMap(uhul.map);

    /*
     * Panel
     */
    uhul.panel = new OpenLayers.Control.Panel(
                                        {displayClass:"hsControlPanel"});
    uhul.map.addControl(uhul.panel);

    /*
     * Layers
     */
    var serverAddress = window;
    var topo = new OpenLayers.Layer.TileCache(
                                gui.gs("Topographical map CR Tiles"),
                                "http://apps.esdi-humboldt.cz/data/tilecache/",
                                'topoJTSK/2M',
                                {format:"image/png"});

    var cenia = new OpenLayers.Layer.TileCache( gui.gs("Arial photos"),
                                "http://apps.esdi-humboldt.cz/data/tilecache/",
                                'ceniaJTSK/2M',
                                {format:"image/jpeg",buffer:1,
                                        });

    var landsat_543 = new OpenLayers.Layer.WMS( "Landsat 543",
                                "http://www.bnhelp.cz/ows/uhul",
                                {layers:"bands543.jpg"},
                                {});

    var single_543 = new OpenLayers.Layer.WMS( "Single 543",
                                "http://www.bnhelp.cz/ows/uhul",
                                {layers:"single543.jpg"},
                                {});

    var landsat_742 = new OpenLayers.Layer.WMS( "Landsat 742",
                                "http://www.bnhelp.cz/ows/uhul",
                                {layers:"bands742.jpg"},
                                {});

    var landsat_123 = new OpenLayers.Layer.WMS( "Landsat 123",
                                "http://www.bnhelp.cz/ows/uhul",
                                {layers:"bands123.jpg"},
                                {});

    var typol = new OpenLayers.Layer.WMS( gui.gs("Forest typology"),
                                "http://geoportal2.uhul.cz/cgi-bin/oprl",
                                {layers:"typol",format:"image/gif",
                                    transparent:true},
                                {isBaseLayer:false,
                                    visibility:false,gutter:50});

    var hs = new OpenLayers.Layer.WMS(gui.gs("Target management class"),
                                "http://geoportal2.uhul.cz/cgi-bin/oprl",
                                {layers:"ciho,ciho_l",format:"image/gif",
                                    transparent:true},
                                { isBaseLayer:false,
                                    visibility:false});

    var topo_transp = new OpenLayers.Layer.TileCache(
                               gui.gs("Topographical map CR - Transparent"),
                               "http://apps.esdi-humboldt.cz/data/tilecache/",
                               'topoOverlayJTSK/2M',
                               {format:"image/gif",
                                isBaseLayer:false,visibility:false});


    uhul.trainingMap = new OpenLayers.Layer.Vector(gui.gs("Training areas"),
                                {group:"training",style:OpenLayers.Feature.Vector.style["default"]});
    
    uhul.map.addLayers([topo,
                        cenia,
                        topo_transp,
                        landsat_543,
                        landsat_742,
                        landsat_123,
                        single_543,
                        typol,
                        hs,
                        uhul.trainingMap]);

    /*
     * Controls and buttons
     */
    uhul.addButtons();
    uhul.map.addControl(new OpenLayers.Control.ArgParser());
    uhul.map.addControl(new OpenLayers.Control.PanZoomBar());
    uhul.map.addControl(new OpenLayers.Control.Scale());
    //uhul.map.addControl(new OpenLayers.Control.KeyboardDefaults());
    uhul.layerSwitcher = new OpenLayers.Control.HSLayerSwitcher( {container:gui.layerSwitcherTab});
    uhul.map.addControl(uhul.layerSwitcher);

    /*
     * End of initialization
     * Set map center
     */
    if (!uhul.map.getCenter()) {
        uhul.map.zoomToMaxExtent();
    }

    uhul.displayLoadingInfo(false);
}



/**
 * Method will create desired map toolbar and append it to map frame
 * @param {String} panelType Type of panel, possible values: "digit"
 *
 */
uhul.addButtons = function(panelType) {


    /* delete panel, if exists */
    if (this.panel) {
        for (var i = 0; i < uhul.panel.controls.length; i++) {
            uhul.map.removeControl(uhul.panel.controls[i]);
            uhul.panel.controls[i].deactivate();
        }
        uhul.map.removeControl(this.panel);
    }
    else {
        return;
    }


    /* create new panel*/
    this.panel = new OpenLayers.Control.Panel(
                                        {displayClass:"hsControlPanel"});
    /* append panel to map */
    uhul.map.addControl(this.panel);

    /* create and append navigation  button for each panel */
    var navButton = new OpenLayers.Control.Navigation();
    this.panel.addControls([navButton]);
    this.panel.activateControl(navButton);

    /* switch panelType */
    if (panelType) {
        hsLayers.addSeparator(this.panel);
        switch(panelType) {

            case "digit":
                    /* polygon drawing button */
                    var polyButton = hsLayers.addButton(
                        {panel:this.panel,
                        type:"polygon", 
                        displayClass:"hsControlDrawFeaturePolygon",
                        description:gui.gs("<b>Define training area</b>"),
                        onDrawingDone: this.onAreaAdded,
                        layer: uhul.trainingMap
                        });
                this.panel.activateControl(polyButton);
                
                /* modify polygon button */
                var modifyOptions = {
                        onModificationStart: uhul.onModifyStart,
                        onModification: function(feature) {
                            OpenLayers.Console.log("modified", feature.id);
                        },
                        onModificationEnd: function(feature) {
                            OpenLayers.Console.log("end modifying",
                                                                feature.id);
                        },
                        onDelete: function(feature) {
                            OpenLayers.Console.log("delete", feature.id);
                        },
                        displayClass: "hsControlModifyFeature"
                    };

                /* the modify button */
                var modifyButton = new OpenLayers.Control.ModifyFeature(
                                            uhul.trainingMap, modifyOptions);
                /* special message when removing features */
                modifyButton.removeFeatureMessage=gui.gs(
                                            "Really delete selected area?");
                this.panel.addControls([modifyButton]);
                hsLayers.addHelp(gui.gs("<b>Edit training area</b>"),
                                modifyButton.panel_div,modifyButton);
                break;
            }
        }
}

/** 
 * Method called, when new area is digitized
 * This method will fill hidden form fields in training areas panel
 * and at the end, the panel will be activated
 */
uhul.onAreaAdded = function(feature) {
    document.getElementById("areaId").value = feature.id;
    document.getElementById("classLabel").value = "";
    document.getElementById("classNr").value = "";
    document.getElementById("areaNote").value = "";
    document.getElementById("useFeature").checked = true;
    document.getElementById("classColor").value = "";
    document.getElementById("areaExists").value = false;

    gui.classifyTabPanel.activate(0);
}

/** 
 * Called, when "Set area attributes" button is clicked
 * The method will collect area attributes from form fields, store it to 
 * 'attributes' object of the feature and make the feature color 
 * acoording to class color
 */
uhul.setAreaAttribute = function() {

    
    /* find desired record in class storage */
    var classNr = document.getElementById("classNr").value; /* number of class */
    var idx = gui.classesStore.find("class",classNr); /* record index */
    var record = gui.classesStore.getAt(idx); /* record */

    /* set class attributes to the digitized feature */
    var classLabel = record.data.label;
    var classColor = record.data.color;
    var useFeature = document.getElementById("useFeature").checked;
    var featureId = document.getElementById("areaId").value;
    var older = document.getElementById("areaExists").value;
    var feature = uhul.trainingMap.getFeatureById(featureId);
    var note = document.getElementById("areaNote").value;
    
    feature.attributes.areaClass=classNr;
    feature.attributes.classLabel=classLabel;
    feature.attributes.classColor=classColor;
    feature.attributes.useFeature=useFeature;
    feature.attributes.areaNote = note;

    /* dispaly digitized feature according to class color */
    var color = "#"+classColor;
    if (!useFeature) { /* feature should not be used -> white */
        color = "#cccccc";
    }

    /* set the color */
    try {
        feature.originalStyle.fillColor = color;
        feature.originalStyle.strokeColor = color;
    }
    catch (e) {
            feature.style.fillColor = color;
            feature.style.strokeColor = color;
    }

    /* redraw */
    uhul.updateFeatuers();
}

/**
 * Called when ever feature attributes or class properties, such as color or
 * derscription were changed
 * Goes trough all features (polygons) in training map and updates it's
 * attributes and colors
 */
uhul.updateFeatuers = function() {

    /* for each feature in training map */
    for (var i = 0; i < uhul.trainingMap.features.length; i++) {
        /* there could be exeption, beceause of some features might not 
           haveany attributes. This happens, if the featues is edited */
        try { 
            var idx = gui.classesStore.find("class",
                        uhul.trainingMap.features[i].attributes.areaClass);
            var record = gui.classesStore.getAt(idx);
            uhul.trainingMap.features[i].attributes.classColor =
                                                        record.data.color;
            uhul.trainingMap.features[i].attributes.classLabel =
                                                        record.data.label;
            var color = "#"+record.data.color;

            if (!uhul.trainingMap.features[i].attributes.useFeature) {
                color = "#cccccc";
            }

            try {
                uhul.trainingMap.features[i].originalStyle.fillColor = color;
                uhul.trainingMap.features[i].originalStyle.strokeColor = color;
            }
            catch (e) {
                uhul.trainingMap.features[i].style.fillColor = color;
                uhul.trainingMap.features[i].style.strokeColor = color;
            }
        }
        catch(e) {
            /* this happens, if features do not have any attributes */
            // console.log(e);
        }
    }
    /* redraw the map */
    uhul.trainingMap.redraw();
}

/**
 * Called, when the user started to modify any feature (training polygon)
 * Sets specified form input fields, with polygon attributes so we can later use them.
 */
uhul.onModifyStart = function(feature) {
    document.getElementById("classNr").value = feature.attributes.areaClass;
    document.getElementById("classColor").value =
                                            feature.attributes.classColor;
    document.getElementById("classLabel").value =
                                            feature.attributes.classLabel;
    document.getElementById("areaId").value = feature.id;
    document.getElementById("areaExists").value = true;
    document.getElementById("areaNote").value = feature.attributes.areaNote;
    document.getElementById("useFeature").checked =
                                            feature.attributes.useFeature;
    /* activate the right panel */
    gui.classifyTabPanel.activate(0);
}


/**
 * Called when "Export" button is clicked. Will call the Web Processing
 * Service, send training areas map in GML format and obtain GML file or
 * zipped SHP, which can be handeld to the user
 * 
 * At the end calles uhul.onSaveAsDone
 */
uhul.onExportTrainingAreas = function () {

    /* get the training map in GML format */
    var g = new OpenLayers.Format.GML();
    var data = g.write(uhul.trainingMap.features);

    /* Inputs for WPS preparation */
    var inputs = {};
    
    /* input */
    inputs.areas = {};
    inputs.areas.value = data;
    inputs.areas.type = "ComplexValue";

    /* output */
    var outputs = {};
    outputs.output = {};
    outputs.output.asReference = true;
    outputs.output.title = "Areas";
    outputs.output.type = "ComplexValue";
    outputs.output.format = {};
    outputs.output.format.mimeType = Ext.get("outputFileFormat").dom.value;

    var ok = uhul.makeWpsRequest("http://www.bnhelp.cz/cgi-bin/wps/uhul",
            "saveAs",
            uhul.onSaveAsDone,
            inputs,
            outputs,
            false,
            true);

};

/**
 * Goes trough all features in the trining map and retunrs GML object made
 * from them
 */
uhul.exportToGML = function () {

    var g = new OpenLayers.Format.GML();
    var features = [];
    var data;

    /* append only features, which are marked to be used for classification
     */
    if (uhul.trainingMap.features.length > 0) {
        for (var i = 0; i < uhul.trainingMap.features.length; i++) { 
            if (uhul.trainingMap.features[i].attributes.useFeature == "true" ||
                uhul.trainingMap.features[i].attributes.useFeature == true) {
                features.push(uhul.trainingMap.features[i]); 
            }
        } 
        data = g.write(features); 
        data = data.replace("<?xml version=\"1.0\"?>","");
    }

    return data;
}

/**
 * Called, when response from the server comes. Offers exported training
 * areas to the user
 * @param {Object} outputs Outputs from WPS response
 */
uhul.onSaveAsDone = function(process) {

    var url = process.outputs[0].getValue();
    var metadata = process.outputs[1].getValue();
    var file = url.split("/")[url.split("/").length-1];
    var suffix = file.split(".")[file.split(".").length-1];
    document.location="http://bnhelp.cz/cgi-bin/getfile.py?file="+
                                        file+"&name=training_areas."+suffix;
};

/**
 * Called when "Classify" button clicked. Prepares input for classification and
 * calls method for execution of the WPS Request
 */
uhul.onClassifyClicked = function() {
    
    /* inputs */
    var inputs = {};

    var extent = uhul.map.getExtent();
    var easting = Math.abs(extent.left-extent.right);
    var northing = Math.abs(extent.top-extent.bottom);
    var res = 30;
    var width = easting/res;
    var height = northing/res;

    /* is the area not too big ? */
    if (easting/res * northing/res > 1000000) {
        
        Ext.MessageBox.alert(gui.gs("Area too wide"),
                        gui.gs("Choosed region has with current resolution")+ 
                            "<br/>Res: "+res+"<br/>"+"["+extent.left+","+
                            extent.bottom+","+extent.right+","+extent.top+ "]");
        return;
    }

    /* training map to GML */
    var areas = uhul.exportToGML();
    if (areas) {
        inputs.training = {};
        inputs.training.value = areas;
        inputs.training.type = "ComplexValue";
    }

    /* input raster map */
    inputs.input = {};
    inputs.input.type = "ComplexValue";
    inputs.input.value = "http://www.bnhelp.cz/ows/uhul?"+
                       "service=WCS&request=getCoverage&crs="+
                        uhul.map.getProjection()+"&"+
                       "coverage=tm&resx="+res+"&resy="+res+
                       "&width="+width+"&height="+height+"&"+
                       "format=image/tiff&bbox="+extent.left+","+
                       extent.bottom+","+extent.right+","+extent.top;
    inputs.input.asReference = true;

    /* column in the attribute table for classification */
    inputs.column = {};
    inputs.column.value = "areaClass";
    inputs.column.type = "LiteralValue";  

    /* number of classes, if unsupervized classification is requested */
    if (document.getElementById("unsupClass").value) {
        inputs.classes = {};
        inputs.classes.value = document.getElementById("unsupClass").value;
        inputs.classes.type = "LiteralValue";  
    }

    /* bands from the imported raster: 6 is thermal */
    inputs.bands = {};
    inputs.bands.value = [1,2,3,4,5,7];
    inputs.bands.type = "LiteralValue";  

    /* block size for GRASS i.smap module */
    inputs.blocksize = {};
    inputs.blocksize.value = document.getElementById("blocksize").value;
    inputs.blocksize.type = "LiteralValue";  

    /* maxsig for GRASS i.gensigset module*/
    inputs.maxsig = {};
    inputs.maxsig.value = document.getElementById("maxsig").value;
    inputs.maxsig.type = "LiteralValue";  
    
    /* use maximum likehood instead of smap? */
    inputs.maxlike = {};
    inputs.maxlike.value = 
                        document.getElementById("maxlikeClassification").checked;
    inputs.maxlike.type = "LiteralValue";  

    /* comma separated list of desired colors for each class */
    var clrs = [];
    for (var i = 0; i < gui.classesStore.data.items.length; i++) {
        var item = gui.classesStore.data.items[i];
        var color = item.data["color"];
        var nr = item.data["class"];

        var red = parseInt(color.substr(0,2),16);
        var green = parseInt(color.substr(2,2),16);
        var blue = parseInt(color.substr(4,2),16);
        clrs.push(nr+" "+red+":"+green+":"+blue);
    }
    inputs.colors = {};
    inputs.colors.value = clrs;
    inputs.colors.type = "LiteralValue";  


    var outputs = {};
    outputs.output = {};
    outputs.output.asReference = true;
    outputs.output.title = document.getElementById("classifyVariant").value;
    outputs.output.type = "ComplexValue";
    outputs.output.mimeType = "image/png";

    outputs.metadata = {};
    outputs.metadata.asReference = true;
    outputs.metadata.title = "Metadata";
    outputs.metadata.type = "ComplexValue";
    outputs.metadata.mimeType = "text/plain";


    uhul.displayLoadingInfo(gui.gs("Classifying variant"));
    var ok = uhul.makeWpsRequest("http://www.bnhelp.cz/cgi-bin/wps/uhul",
                            "classify",
                            uhul.onClassificationDone,
                            inputs,
                            outputs,
                            false,
                            true);
};

/**
 * Classification done, display the resulting map
 * The resulting map will be displayed in the map, other will be turned off and
 * the map will also be displaied in the postprocessing combo box
 *
 * @param {Object} outpus outpus from the WPS response
 */
uhul.onClassificationDone = function(process) {
    
    /* get the desired variant name */
    var layerName = process.outputs[0].title;

    /* create new OpenLayers.Layer.Image object */
    var classify = new OpenLayers.Layer.Image(
            layerName, process.outputs[0].getValue(),
            uhul.map.getExtent(), uhul.map.getSize(), 
            {group:layerName+"-class", removable:true,
                metadataURL: process.outputs[1].getValue(),
             isBaseLayer:false,buttonDropLayer:true,
            source:process.outputs[0].getValue(),
	    maxResolution : uhul.map.baseLayer.maxResolution,
	    minResolution : uhul.map.baseLayer.minResolution
	     } );


    classify.setOpacity(0.5);
    uhul.map.addLayer(classify);

    gui.classifiedLayersStore.removeAll();
    var data = [];

    for (var i = 0; i < uhul.classLayers.length; i++) {
	try {
		uhul.classLayers[i].setVisibility(false);
		data.push([uhul.classLayers[i].id,uhul.classLayers[i].name]);
	}
	catch(e) {
	}
    }
    uhul.classLayers.push(classify);
    data.push([classify.id,classify.name]);

    /* add all layers to the combo box */
    gui.classifiedLayersStore.loadData(data);

    uhul.displayLoadingInfo(false);
};

/**
 * TODO: Method for reading classes from some XML or what ever. To be done
 */
uhul.readClassAttributes = function() {
};

/**
 * Displayes "Loading ..." box in the map, so the user can see, that something
 * is happening.  @param {String} message Message, which should be displayed.
 * If ommited, the box will disappear
 */
uhul.displayLoadingInfo = function(message) {
    try {
        if (!message) {
            gui.loadmask.hide();
        }
        else {
            gui.loadmask = new Ext.LoadMask(
                    document.getElementById("map"),{msg:message});
            gui.loadmask.show();
        }
    }
    catch (e) {
        window.setTimeout(uhul.displayLoadingInfo,1000);
    }
};

/**
 * Method which gets GML file and appends classes avaialable in the file to
 * classes store, so they appear in the classes table. It also appends new
 * digitized featrues to the training map
 * @param {String} resp XMLHttp response object
 */

uhul.loadNewTrainingAreas = function(resp) {

    /* make featues from GML */
    var g =  new OpenLayers.Format.GML();
    var features = g.read(resp.responseText);

    /* delete allready digized featues, if checkbox checked */
    if (document.getElementById("fileDeleteOrig").checked) {
        uhul.trainingMap.removeFeatures(uhul.trainingMap.features);
    }

    /* add new featues */
    uhul.trainingMap.addFeatures(features);

    /*
     * parse all features and pick up classes from them
     */
    var classes = [];
    var west = null;
    var south= null;
    var east = null;
    var north = null;

    /* for each feature */
    for (var i = 0; i < uhul.trainingMap.features.length; i++) {

        if (!uhul.trainingMap.features[i].style) {
            uhul.trainingMap.features[i].style = {};
        }
        /* set color and attributes */
        uhul.trainingMap.features[i].style.fillColor = 
                    "#"+uhul.trainingMap.features[i].attributes["classColor"];
        uhul.trainingMap.features[i].style.strokeColor =
                    "#"+uhul.trainingMap.features[i].attributes["classColor"];
        attributes = uhul.trainingMap.features[i].attributes;

        /* calculate maximal bbox, so we can later zoom to it  */
        var bounds = uhul.trainingMap.features[i].geometry.getBounds();
        if (i == 0) {
            west = bounds.left;
            south = bounds.bottom;
            east = bounds.right;
            north = bounds.top;
        }
        else {
            west = (bounds.left < west ? bounds.left : west);
            south = (bounds.bottom < south ? bounds.bottom : south);
            east = (bounds.right > east ? bounds.right : east);
            north = (bounds.top > north ? bounds.top : north);
        }

        /* if the class does not exist yet, append it to the table */
        var exists = false;
        for (var j = 0; j < classes.length; j++) {
            if (classes[j]["areaClass"] == attributes["areaClass"]) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            classes.push(attributes);
        }
    }

    /* for each new class, append to the table */
    for (i = 0; i < classes.length; i++) {
        gui.addNewRecordToClassTable(gui.classesStore.data.items.length+1,
                                    classes[i]["classLabel"],
                                    classes[i]["classColor"] );
    }

    /* redraw training map and zoom to new features */
    uhul.trainingMap.redraw();
    uhul.map.zoomToExtent(new OpenLayers.Bounds(west,south,east,north));
};

/**
 * Method called, when "Postprocess" button clicked
 */
uhul.onPostprocess = function() {

    /* inputs */
    var inputs = {};

    /* input classified raster map */
    var layer = uhul.map.getLayer(document.getElementById("classedLayerId").value);
    if (!layer){
        Ext.MessageBox.alert ("ERROR: no layer selected",
                gui.gs("No classified layer was selected")); 
        return; 
    }

    inputs.input = {};
    inputs.input.value = layer.source;
    inputs.input.asReference = true;
    inputs.input.type = "ComplexValue";  

    /* r.neighbors method */
    /*
    inputs.method = {};
    inputs.method.value = document.getElementById("neigbhborsMethod").value;
    inputs.method.type = "LiteralValue";  
    */

    /* matrix size */
    inputs.size = {};
    inputs.size.value = document.getElementById("matrixSize").value;
    inputs.size.type = "LiteralValue";  

    outputs  = {};
    outputs.output = {}
    outputs.output.asReference = true;
    outputs.output.title = document.getElementById("postprocessedVariant").value;
    outputs.output.type = "ComplexValue";
    outputs.output.mimeType = "image/png";

    /* perform WPS request */
    uhul.displayLoadingInfo(gui.gs("Postprocessing variant"));
    var ok = uhul.makeWpsRequest("http://www.bnhelp.cz/cgi-bin/wps/uhul",
                            "neighbors",
                            uhul.onPostprocessingDone,
                            inputs,
                            outputs,
                            false,
                            true);
};

/**
 * Postprocessing process done, parse the outputs: Append new layer to layer list
 * @param {Object} outputs WPS Response outputs
 */
uhul.onPostprocessingDone = function(processes) {

    
    /* get the desired variant name */
    var layerName = document.getElementById("postprocessedVariant").value ? document.getElementById("postprocessedVariant").value : "unnamed";

    /* name -> name-2 */
    for (var i = 0; i < uhul.map.layers.length; i++) {
        if (uhul.map.layers[i].name == layerName){
            var nr = layerName.split("-").length;
            if (nr == 1) {
                layerName += "-1";
            }
            else if (nr > 2){
                layerName = layerName.split("-")[0]+parseInt(layerName.split("-")[nr]+1);
            }
        }
    }

    /* create new OpenLayers.Layer.Image object */
    var postprocess = new OpenLayers.Layer.Image(
            layerName, processes.outputs[0].getValue(),
            uhul.map.getExtent(), uhul.map.getSize(), 
            {removable:true, group:layerName+"post",
	     isBaseLayer:false,buttonDropLayer:true,
            source:processes.outputs[0].getValue()} );
    postprocess.setOpacity(0.5);

    uhul.map.addLayer(postprocess);

    /* HACK HACK: we want to see the map in all resolutions */
    postprocess.maxResolution = uhul.map.baseLayer.maxResolution;
    postprocess.minResolution = uhul.map.baseLayer.minResolution;
    postprocess.redraw();

    for (var i = 0; i < uhul.postprocessedLayers; i++) {
	try {
		uhul.postprocessedLayers[i].setVisibility(false);
	}
	catch(e){}
        uhul.postprocessedLayers[i].setVisibility(false);
    }

    for (var i = 0; i < uhul.classLayers.length; i++) {
	try {
		uhul.classLayers[i].setVisibility(false);
	}
	catch(e) {
	}
    }

    uhul.postprocessedLayers.push(postprocess);
    uhul.displayLoadingInfo(false);
};

/**
 * Method: makeWpsRequest
 * Provides WPS request
 * 
 * Parameters:
 * serverName {String} serverName WPS server URL
 * processName {String} processName WPS process name
 * onDone {Function} onDone function to be called onReadyStageChanged
 * dataInputs {Object} dataInputs proces data inputs
 * assynchronous {Boolean} assynchronous run assynchronously
 * parse {Boolean} parse the outputs automaticaly - will return Object with outputs, not xmlDom
 *
 * Returns:
 * {Boolean} request ok
 */
uhul.makeWpsRequest = function(serverName, processName, onDone, dataInputs, dataOutputs, assynchronous,parse) {

    wps = new OpenLayers.WPS(serverName,{onSucceeded:onDone});

    // for each input
    var inputs  = []
    for (input in dataInputs) {

        if (typeof(dataInputs[input].value) != typeof([])) {
            dataInputs[input].value = [dataInputs[input].value];
        }
        for (var i = 0; i < dataInputs[input].value.length; i++) {

            var wpsinput;
            // ComplexValue
            switch(dataInputs[input].type) {
                case "ComplexValue": 
                    wpsinput = new OpenLayers.WPS.ComplexPut({identifier:input,
                                value : dataInputs[input].value[i],
                                asReference: dataInputs[input].asReference});
                    break;
                case "LiteralValue":
                    wpsinput = new OpenLayers.WPS.LiteralPut({identifier:input,
                                value : dataInputs[input].value[i]
                                });
                    break;
                case "BoundingBoxValue":
                    wpsinput = new OpenLayers.WPS.BoundingBoxPut({identifier:input,
                                value : [dataInputs[input].value[i].left,
                                        dataInputs[input].value[i].bottom,
                                        dataInputs[input].value[i].right,
                                        dataInputs[input].value[i].top]
                                });
                default:
                    throw new Error("HSLayers.makeWpsRequest: input type '"+dataInputs[input].type+"' unknown!");
                    break;
            }
            inputs.push(wpsinput);
        }
    }

    var outputs = [];
    for (out in dataOutputs) {
        var output;
        switch(dataOutputs[out].type) {
            case "ComplexValue": 
                output = new OpenLayers.WPS.ComplexPut({identifier:out,
                            title: dataOutputs[out].title,
                            format: {mimeType: dataOutputs[out].mimeType},
                            asReference: dataOutputs[out].asReference});
                break;
        }
        outputs.push(output);
    }
    var process = new OpenLayers.WPS.Process({identifier: processName,
            inputs: inputs,
            outputs: outputs});
    wps.addProcess(process);
    wps.scope = this;


    wps.execute(processName);
};

/**
 * provides WPS request
 * @param {XMLDom} xmldom DOM representation of WPS response document
 * @return {Object} Object with parsed Outputs or error, if any
 */
uhul.parseWpsResponse = function(process) {

     uhul.onClassificationDone(process.outputs);
     uhul.xmlHttp = null;
     uhul.onWPSDone = null;
};

uhul.classLayers = [];
uhul.postprocessedLayers = [];

