/*
 * Functionaliteit voor het intekenen, iploaden en toetsen van het plangebied.
 *
 */
// Globale variabelen
var tetoetsenPlangebied = null;
var beperkingen = null;
var beperkingGeraakt = false;

// Id van de waterschap waarmee de toets wordt uitgevoerd.
// Wordt bepaald en geset in BepaalWaterschappen (watertoets_zoeken.js)
var currentWaterschapId = -1;
  
// Naam van de waterschap waarmee de toets wordt uitgevoerd
// Wordt bepaald en geset in BepaalWaterschappen (watertoets_zoeken.js)
var currentWaterschap = null;

// ";" separated string met de ids van waterschappen waarin het plangebied ligt
// Wordt bepaald en geset in BepaalWaterschappen (watertoets_zoeken.js)
var currentWaterschappen = "";

// Gemeentenaam van de gemeente waarin het grootste deel van het plangebied ligt.
// Wordt bepaald en geset in BepaalGemeente (watertoets_zoeken.js)
var currentGemeenteNaam = "";

/*
 * Structuur voor opslag toetsresultaat tegen een beperking
 */
function Beperking(title, description, hit){
    this._title = title;
    this._description = description;
    this._hit = hit;
}

/*
 * Toevoegen van een beperking
 */
function addBeperking(beperkingen, beperking){
    var key = beperking._title;
    if (beperkingen[key] == undefined) {
        beperkingen[key] = beperking;
    }
}

/*
 * Testfunctie
 * TODO: verwijder
 */
function _populateBeperkingDialog(){
    var s = "";
    
    for (key in beperkingen) {
        var beperking = beperkingen[key];
        s += key + ' - ' + beperking._title + " - " + beperking._hit + "\n";
    }
    hideProgressBar();
    alert(s);
}

/*
 * Zet tijdens het toetsen en aanmaken van de snapshot de knoppen op het resultaatscherm op disabled
 */
function disableNavigateButtons(state){
    var nextButton = dojo.byId("nextButton");
    if(nextButton) nextButton.disabled = state;
    
    var previousButton = dojo.byId("previousButton");
    if(previousButton) previousButton.disabled = state;
    
    var divEl = dojo.byId("toetsResultDiv");
    dojo.style(divEl, "cursor", state ? "wait" : "default");
    divEl.title = state ? "Even geduld, er wordt een afbeelding gemaakt van het kaartbeeld..." : "";

    console.debug("Buttonstate: " + state);
}

/*
 * Keten van eventhandlers:
 * executeWatertoets -> bepaalGemeente -> handleIntersectedGemeentes -> 
 *    bepaalWaterschap -> handleIntersectedWaterschappen -> findIntersectedBeperkingen -> 
 *        handleIntersectedBeperkingen -> handleAllBeperkingen -> populateBeperkingDialog
 */

/*
 * Toon het resultatenscherm.
 */
function populateBeperkingDialog(){
    // Laat het resultaat zien
    activateDiv('toetsResultDiv');
    
    console.debug("Vul waterschap en gemeente omschrijving");
    var el = dojo.byId('waterschap');
    el.innerHTML = 'Watertoets uitgevoerd voor waterschap: <span class="wsnaam">' + currentWaterschap[WS_FIELDS._WSNAAM] + "</span>,<br/> in de gemeente " + currentGemeenteNaam + "<br/><hr/>";
    
    // Sla het resultaat van de toets op in een hidden field
    var beperkingGeraaktHidden = dojo.byId('map_beperking');
    if (beperkingGeraaktHidden) {
        beperkingGeraaktHidden.value = beperkingGeraakt ? "ja" : "nee";
        console.debug("Beperking geraakt: " + beperkingGeraaktHidden.value);
    }
    
    // Vul de resultaattabel
    fillResultTable();
    
    //disable buttons
    disableNavigateButtons(true);
    
    console.debug('getting plan image');
    var snapshotBuilder = new SnapshotBuilder(AquaWT.map, tetoetsenPlangebied);
    snapshotBuilder.getSnapshot();
    
    hideProgressBar();
}

function bepaalWaterschapKaartLagen(){
  var queryTask = new esri.tasks.Geoprocessor(gpServiceUrl + "/BeperkingenLagen");
  var sql = "WSID = "+ currentWaterschapId;
  console.log(sql);
  var params = { "sqlWaterSchapId" : sql};
  queryTask.execute(params, handleAllGpBeperkingen, cancelWatertoets);
}

function handleAllGpBeperkingen(results, messages){
  var features = results[0].value.features;
  handleAllBeperkingen(features);
}

function errorBeperkingen(error) {
  hideProgressBar();
  console.log('Fout in BeperkingenLagen: ' + error);
  toggleElement('infoDiv',true);
  alert("Er is een fout opgetreden bij het bepalen van de kaartlagen. Probeer het nog een keer.");
}

/*
 * Haal alle beperkingen op en vul de lijst met geraakte beperkingen aan.
 */
var MAXRECORDCOUNT = 500;
function countAllBeperkingen(results){
  var numberOfFeatures = results.features.length;
  console.log(numberOfFeatures);
  
  /*
   * QueryTask geeft maximaal 500 records terug (dit is instelbaar als MaxRecordCount in 
   * beperkingen.MapServer.cfg)
   * Indien het aantal record gelijk is aan 500 dan is dit maximum bereikt en zullen de kaartlagen met behulp
   * van de geoprocessing service bepaald moeten worden.
   */
  if(numberOfFeatures >= MAXRECORDCOUNT) {
    console.log("Bepaal kaartlagen met gp service");
    bepaalWaterschapKaartLagen();
  }
  else {
    handleAllBeperkingen(results.features);
  }
}

/*
 * Vul de lijst met geraakte beperkingen aan met de niet geraakte beperkingen
 */
function handleAllBeperkingen(features){
    var numberOfFeatures = features.length;
    console.log("handleAllBeperkingen: " + numberOfFeatures);
    for (var i = 0; i < numberOfFeatures; i++) {
        var feature = features[i];
        var beperking = new Beperking(feature.attributes["Title"], feature.attributes["Descrip"], false);
        addBeperking(beperkingen, beperking);
    }
    populateBeperkingDialog();
}

/*
 * Maak een lijst met geraakte beperkingen. Zet beperkingGeraakt op true.
 */
function handleIntersectedBeperkingen(results){
    var numberOfFeatures = results.features.length;
    beperkingen = new Object();
    
    for (var i = 0; i < numberOfFeatures; i++) {
        var feature = results.features[i];
        var beperking = new Beperking(feature.attributes["Title"], feature.attributes["Descrip"], true);
        addBeperking(beperkingen, beperking);
        beperkingGeraakt = true;
    }
    
    var queryTask = new esri.tasks.QueryTask(toetsLayerUrl + "/0");
    dojo.connect(queryTask, "onComplete", countAllBeperkingen);
    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = false;
    query.outFields = ["Title", "Descrip", "OBJECTID"];
    query.where = 'WSID=' + currentWaterschapId;
    queryTask.execute(query);
}
/*
 * Zoek de beperkingsgebieden die door het plangebied geraakt (intersected) worden.
 */
function findIntersectedBeperkingen(){
    // Vul het hidden field map_waterschap
    setWaterschapId();
    setWaterschappen();
    
    // Controleer of het waterschap deelnemer is aan De Digitale Watertoets
    if(currentWaterschap[WS_FIELDS._WSDEELNEMERSHP] == 0) {
      alert(WT_MSG.GROOTSTWSGEENDEELNEMER);
      hideProgressBar();
      toggleElement('infoDiv',true);
      return;
    }
    
    // Set querydef op beperkingen laag
    var layerDefs = [];
    layerDefs[INDEX_LIM] = "WSID = " + currentWaterschapId;
    
    var layer = AquaWT.map.getLayer(TOETSLAYER);
    console.log(layer.id + ' - ' + layerDefs[INDEX_LIM]);
    layer.setLayerDefinitions(layerDefs);
    
    
    // Voer de watertoets uit 
    var queryTask = new esri.tasks.QueryTask(toetsLayerUrl + "/0");
    dojo.connect(queryTask, "onComplete", handleIntersectedBeperkingen);
    
    // build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = false;
    query.outFields = ["Title", "Descrip", "OBJECTID"];
    query.geometry = tetoetsenPlangebied.geometry;
    query.where = 'WSID=' + currentWaterschapId;
    queryTask.execute(query);
    
    dojo.unsubscribe(toetsPlanHandle);
}

/*
 * In geval het plangebied in meerdere waterschappen ligt moet de watertoets
 * in het waterschap uitgevoerd worden waar het grootste deel van het plangebied ligt.
 * deze functie bepaald met behulp van een (trage) geoprocessing tool dit waterschap.
 */
var toetsPlanHandle = null;
var errorWSHandle = null;
function bepaalGrootsteIntersectedWaterschap(){
    var bepaalWaterschap = new BepaalWaterschap(AquaWT.map, gpServiceUrl + "/BepaalWaterschap");
    
    // Subscribe op de execute completed van BepaalWaterschap
    toetsPlanHandle = dojo.subscribe(LARGEST_INTERSECTED_WATERBOARD, this, "findIntersectedBeperkingen");
    errorWSHandle = dojo.subscribe(ERROR_INTERSECTED_WATERBOARD, this, "cancelWatertoets");

    bepaalWaterschap.execute(tetoetsenPlangebied);
}

/*
 * Haal de waterschapid en naam uit het resultaat. Wanneer er meedere waterschappen 
 * zijn gevonden wordt de geoprocessing tool gestart om te bepalen in welke 
 * waterschap het grootste deel van het plangebied ligt.
 */
function handleIntersectedWaterschappen(results){
    var numberOfFeatures = results.features.length;
    if (numberOfFeatures == 0) {
        alert("Geen waterschap gevonden");
    }
    else {
        if (numberOfFeatures > 1) {
            bepaalGrootsteIntersectedWaterschap();
        }
        else {
            currentWaterschapId = results.features[0].attributes["CBS_CODE"];
            currentWaterschap = results.features[0].attributes;
            
            // Voer nu de watertoets uit.
            findIntersectedBeperkingen();
        }
        
    }
}

/*
 * Sla de waterschapid op in een hidden field voor verwerking in de database.
 */
function setWaterschapId(){
  setInputValue('map_waterschap',currentWaterschapId);
}

function setWaterschappen(){
  setInputValue('map_waterschappen',currentWaterschappen);
}

/*
 * Bepaal de waterschap waarin het plangebied getekend is.
 */
function bepaalWaterschap(){
  var queryTask = new esri.tasks.QueryTask(achtergrondLayerUrl + "/" + INDEX_WS);
  dojo.connect(queryTask, "onComplete", handleIntersectedWaterschappen);
  
  //build query filter
  var query = new esri.tasks.Query();
  query.returnGeometry = false;
  query.outFields = ["NAAM", "CBS_CODE", "OBJECTID"];
  query.geometry = tetoetsenPlangebied.geometry;
  query.where = '1=1';
  queryTask.execute(query);
  
  dojo.unsubscribe(searchCMHandle);
}


/*
 * In geval het plangebied in meerdere gemeentes ligt moet de bepaald worden waar het 
 * grootste deel van het plangebied ligt. Deze functie bepaald met behulp van een 
 * geoprocessing tool deze gemeente.
 */
var searchCMHandle = null;
var errorCMHandle = null;
function bepaalGrootsteIntersectedGemeente(){
    var bepaalGemeente = new BepaalGemeente(AquaWT.map, gpServiceUrl + "/BepaalGemeente");
    
    // Na uitvoering van bepaalGemeente.execute wordt LARGEST_INTERSECTED_COMMUNITY gepublished.
    searchCMHandle = dojo.subscribe(LARGEST_INTERSECTED_COMMUNITY, this, "bepaalWaterschap");
    errorCMHandle = dojo.subscribe(ERROR_INTERSECTED_COMMUNITY, this, "cancelWatertoets");
    
    if (bepaalGemeente) {
        console.log(currentGemeenteNaam);
        bepaalGemeente.execute(tetoetsenPlangebied);
    }
}

/*
 * Haal de gemeentenaam uit het queryresultaat
 */
function handleIntersectedGemeentes(results){
    var numberOfFeatures = results.features.length;
    if (numberOfFeatures == 0) {
        alert("Geen gemeente gevonden");
    }
    else {
        if (numberOfFeatures > 1) {
            bepaalGrootsteIntersectedGemeente();
        }
        else {
            currentGemeenteNaam = results.features[0].attributes["OMSCHRIJVI"];
            setGemeenteNaam();
            bepaalWaterschap();
        }
    }
}

function setGemeenteNaam(){
  setInputValue('map_gemeente',currentGemeenteNaam);
}

/*
 * Bepaal de gemeente waarin het plangebied getekend is.
 */
function bepaalGemeente(){
    var queryTask = new esri.tasks.QueryTask(achtergrondLayerUrl + "/" + INDEX_CM);
    dojo.connect(queryTask, "onComplete", handleIntersectedGemeentes);
    
    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = false;
    query.outFields = ["OMSCHRIJVI", "OBJECTID"];
    query.geometry = tetoetsenPlangebied.geometry;
    query.where = '1=1';
    queryTask.execute(query);
}

/*
 * Voer de watertoets uit.
 */
function executeSlowWatertoets(plangebied){
  tetoetsenPlangebied = plangebied;
  bepaalGemeente();
}

function cancelWatertoets() {
  hideProgressBar();
  toggleElement('infoDiv',true);
  alert("Er is een fout opgetreden bij het toetsen. Probeer het later nog een keer!");
  dojo.unsubscribe(errorWSHandle);  
  dojo.unsubscribe(errorCMHandle);
}

/*
 * Voer de watertoets uit.
 */
function executeWatertoets(plangebied){
  tetoetsenPlangebied = plangebied;

  var polygonString = getGeometryAsPointsString(plangebied.geometry);

  postWatertoets(polygonString);
}

function getGeometryAsPointsString(polygon) {
  var rings = polygon.rings;
  var polygonString = "";
  
  for(var ringIndex=0; ringIndex < rings.length ; ringIndex++){
    var nrpoints = rings[ringIndex].length;
    
    for(var pointIndex = 0; pointIndex < nrpoints; pointIndex++) {
      var point = polygon.getPoint(ringIndex, pointIndex)
      polygonString += point.x + "," + point.y + (pointIndex < nrpoints-1 ? ";" : "");
    }
    
  }
  return polygonString;
}


function postWatertoets(polygonString) {
  var checkServiceUrl = serverHost + "/watertoetsCheck/Check.ashx";

  dojo.xhrPost({
      content: {"polygonString": polygonString},
      url: checkServiceUrl,
      load: onSucces,
      error: onError
  });
}

function onSucces(data) {
    console.log(data);
    var jsonResults = dojo.fromJson(data);
    parseResults(jsonResults);
}

function onError(data, error) {
    console.log(data);
    console.log(error);
    cancelWatertoets();
}

function parseResults(jsonResults){
  if(jsonResults.ErrorMessage != "Ok" || jsonResults.HasErrors ) {
    alert("Er is een fout opgetreden bij het toetsen.");
    cancelWatertoets();
    return; 
  }
  
  var gemeentes = jsonResults.Municipalities;
  if (gemeentes.length > 0) {
    var gemeenteNaam = jsonResults.Municipalities[0].Name;
    setInputValue('map_gemeente', gemeenteNaam);
  }
  
  // Waterschappen
  var waterschappen = jsonResults.WaterBoards;
  var nrOfWs = waterschappen.length;
  
  if(nrOfWs == 0) {
    alert("Geen waterschap gevonden!");
    return;
  }

  var waterschap = waterschappen[0];
  currentWaterschapId = waterschap.Id;  // blijf compatibel met voorgaande toetsmethode
  setInputValue('map_waterschap',currentWaterschapId);

  console.debug("Vul waterschap en gemeente omschrijving");
  var el = dojo.byId('waterschap');
  el.innerHTML = 'Watertoets uitgevoerd voor waterschap: <span class="wsnaam">' + waterschap.Name + "</span>,<br/> in de gemeente " + gemeenteNaam + "<br/><hr/>";


 
  // Haal ids van de andere geraakte waterschappen
  currentWaterschappen = "";
  if (nrOfWs > 1) {
    for(var i=1; i < nrOfWs; i++) {
      currentWaterschappen += waterschappen[i].Id + ";"; 
    }
  }
  setInputValue('map_waterschappen',currentWaterschappen);


  // Verwerk beperkingen
  beperkingen = new Object();

  var constraints = jsonResults.WaterBoards[0].ConstraintAreaCategories;
  var numberOfResults = constraints.length;
  //var layers_hit = "";
  beperkingGeraakt = false;
  
  console.log("Aantal beperkingen geraakt: " + numberOfResults);
  for (var i = 0; i < numberOfResults; i++) {
    var constraint = constraints[i];
    var beperking = new Beperking(constraint.Name, constraint.Description, constraint.Hit);
    addBeperking(beperkingen, beperking);

    if(constraint.Hit) {
      beperkingGeraakt = true;
    }    
    //layers_hit += constraint.Name + (constraint.Hit ? ":ja" : ":nee") + (i < numberOfResults-1 ? ";" : ""); 
  }

  // Sla het resultaat van de toets op in een hidden field
  setInputValue('map_beperking',(beperkingGeraakt ? "ja" : "nee"));
  
  //setInputValue("map_constraints_hit",layers_hit);
  setInputValue("map_constraints_hit",dojo.toJson(constraints,false));
  
  populateBeperkingenDialog();
}

function populateBeperkingenDialog(){
    // Laat het resultaat zien
    activateDiv('toetsResultDiv');
    
    // Vul de resultaattabel
    fillResultTable();
    
    //disable buttons
    disableNavigateButtons(true);
    
    console.debug('getting plan image');
    var snapshotBuilder = new SnapshotBuilder(AquaWT.map, tetoetsenPlangebied);
    snapshotBuilder.getSnapshot();
    
    hideProgressBar();
}


/* 
 * Vul de tabel van het toetsresultaatscherm
 */
function fillResultTable(){
    console.debug("Bouw tabel resultsTable");
    
    var resultTable = dojo.byId('resultsTable');
    while (resultTable.childNodes.length > 0) {
        resultTable.removeChild(resultTable.firstChild);
    }
    
    var thead = document.createElement("thead");
    resultTable.appendChild(thead);
    
    var tr = document.createElement("tr");
    thead.appendChild(tr);
    
    var th = document.createElement("th");
    th.id = 'thToon';
    dojo.addClass(th, 'toon');
    th.appendChild(document.createTextNode('Toon'));
    tr.appendChild(th);
    
    var th = document.createElement("th");
    th.id = 'thKaartlaag';
    dojo.addClass(th, 'kaartlaag');
    th.appendChild(document.createTextNode('Kaartlaag'));
    tr.appendChild(th);
    
    var th = document.createElement("th");
    th.id = 'thResultaat';
    dojo.addClass(th, 'resultaat');
    th.appendChild(document.createTextNode('Resultaat'));
    tr.appendChild(th);
    
    var th = document.createElement("th");
    th.id = 'thInfo';
    dojo.addClass(th, 'info');
    th.appendChild(document.createTextNode('Info'));
    tr.appendChild(th);
    
    
    var tbody = document.createElement("tbody");
    resultTable.appendChild(tbody);
    
    
    /* Bouw een tabel met de resultaten 
     * ipv dojox.grid, die werkt nog niet echt lekker...
     */
    console.debug("Vul resultaat tabel");
    var r = 0;
    for (key in beperkingen) {
        var beperking = beperkingen[key];
        if (beperking._title !== undefined) {
            console.debug(beperking._title + " - " + beperking._hit);
            
            var row = document.createElement("tr");
            
            var col1 = document.createElement("td");
            var cb1 = document.createElement("input");
            cb1.id = 'visibleLayer' + r;
            cb1.type = 'checkbox';
            cb1.title = 'Klik om de kaartlaag aan of uit te zetten.'
            cb1.onclick = toggleLayer;
            cb1.checked = false;
            
            dojo.addClass(col1, 'toon');
            col1.appendChild(cb1);
            row.appendChild(col1);
            
            var col2 = document.createElement("td");
            col2.innerHTML = beperking._title;
            dojo.addClass(col2, 'kaartlaag');
            row.appendChild(col2);
            
            var col3 = document.createElement("td");
            var img3 = document.createElement("span");
            img3.className = beperking._hit ? 'toetsBelang' : 'toetsGeenBelang';
            col3.appendChild(img3);
            dojo.addClass(th, 'resultaat');
            row.appendChild(col3);
            
            var col4 = document.createElement("td");
            var img4 = document.createElement("span");
            img4.className = 'helpLayer';
            dojo.addClass(th, 'info');
            col4.appendChild(img4);
            
            // Ietwat ingewikkelde constructie om mouseover te tonen...
            (dojo.hitch(this, function(){
                var d = beperking._description;
                
                dojo.connect(col4, "onmouseover", function(evt){
                    showTip(d)
                });
            }))();
            
            col4.onmouseout = UnTip;
            row.appendChild(col4);
            
            console.debug('Resulttable rij: ' + r);
            tbody.appendChild(row);
        }
        r++;
    }
}

/*
 * Zet beperkingenlagen aan/uit dmv layer definitions.
 * Vanwege de opzet van de beperkingenlaag kan dit alleen op deze manier.
 */
function toggleLayer(){
    /* Zet alle aangevinkte beperkingen aan */
    var sql = "WSID = " + currentWaterschapId;
    
    var chk = 0;
    var r = 0;
    for (key in beperkingen) {
        var beperking = beperkingen[key];
        if (beperking._title !== undefined) {
            var cb = dojo.byId('visibleLayer' + r);
            if (cb.checked) {
                var logic = chk == 0 ? ' AND ( ' : ' OR ';
                chk++;
                sql += logic + " Title = '" + beperking._title + "'";
            }
        }
        r++;
    }
    
    if (chk > 0) {
        sql += ' )'
    }
    else {
        sql += " AND Title = 'NONE'"
    }
    
    
    var layerDefs = [];
    layerDefs[INDEX_LIM] = sql;
    
    var layer = AquaWT.map.getLayer(TOETSLAYER);
    console.debug(layer.id + ' - ' + layerDefs[INDEX_LIM]);
    layer.setLayerDefinitions(layerDefs);
    
    /* Zet de Beperkingen laag aan */
    var visible = [];
    
    var infos = layer.layerInfos, info;
    for (var i = 0, il = infos.length; i < il; i++) {
        info = infos[i];
        visible.push(info.id);
    }
    
    layer.setVisibleLayers(visible);
}

function turnOffBeperkingen(){
  /* Zet de Beperkingen laag aan/uit */
  var layer = AquaWT.map.getLayer(TOETSLAYER);
  layer.setDefaultLayerDefinitions();
  layer.setVisibleLayers([]);
}


//*************************************************************************************************************************
// Snapshotbuilder
//
// defined in watertoets_common.js 
// var _annotatorBase = "http://www.dewatertoets.nl/imageannotator/";
var _annotatorService = "ImageAnnotation.ashx";

dojo.declare("SnapshotBuilder", null, {
    //fields     
    _map: null,
    _planGebied: null,
    
    //constructor
    constructor: function(map, drawArea){
        this._map = map;
        this._drawArea = drawArea;
    },
    
    //public methods
    getSnapshot: function(){
        if (this._drawArea === null) {
            console.debug("no area drawn");
            return;
        }
        
        var map = this._map;
        
        
        // get urls of all layers
        
        var urls = "";
        for (var i = 0; i < map.layerIds.length; i++) {
            var layer = map.getLayer(map.layerIds[i]);
            if (urls != "") {
                urls += "#";
            }
            urls += layer.url;
        }
        console.debug(urls);
        
        var shape = this._drawArea.getDojoShape();
        // Bij de overgang van JS API 1.3 naar 1.4 wordt shape.shape.path in IE niet meer
        // geset. De waarde staat in vmlPath.
        var drawPath = dojo.isIE ? shape.vmlPath : shape.shape.path;
        console.debug("drawPath: "+ drawPath);

        var dxparent = shape.parent.matrix.dx; 
        var dyparent = shape.parent.matrix.dy; 
        var dx = shape.parentMatrix ? shape.parentMatrix.dx : 0;
        var dy = shape.parentMatrix ? shape.parentMatrix.dy : 0;
        
        //var dx = dxparent - shapedx;
        //var dy = dyparent - shapedy; 
        
        // Soms geeft parentMatrix floats terug. Daarom afronden.
        dx = 0;//Math.round(dx);
        dy = 0;//Math.round(dy);
        var offsetString = dx.toString() + "," + dy.toString();
        console.debug("offsetstring: "+ offsetString);

        dxparent = Math.round(dxparent);
        dyparent = Math.round(dyparent);
        var shapeOffsetString = dxparent.toString() + "," + dyparent.toString();
        console.debug("shapeoffsetstring: "+ shapeOffsetString);
        
        // get map extent
        var imageSizeString = map.width.toString() + "," + map.height.toString();
        var extent = map.extent;
        var extentString = extent.xmin.toString() + "," +
        extent.ymin.toString() +
        "," +
        extent.xmax.toString() +
        "," +
        extent.ymax.toString();
        console.debug("extentString: "+ extentString);
        
        var scaleBarPath = getScaleBarShape();
        console.debug("scaleBarPath: "+ scaleBarPath[0]);
        console.debug("scaleBartext: "+ scaleBarPath[1]);
        console.debug("disclaimer: "+ scaleBarPath[2]);
        
        dojo.xhrPost({
            url: _annotatorBase + _annotatorService,
            content: {
                "imageSize": imageSizeString,
                "extent": extentString,
                "layerUrls": urls,
                "drawPath": drawPath,
                "drawPathOffset": offsetString,
                "shapeOffset": shapeOffsetString,
                "scaleBarPath" : scaleBarPath[0],
                "scaleBarText" : scaleBarPath[1],
                "disclaimer" : scaleBarPath[2]
            },
            load: function(data){
                var imgUrl = _annotatorBase + data;
                setInputValue("map_snapshot",imgUrl);

                disableNavigateButtons(false);
            },
            error: function(data){
                alert("Er is iets fout gegaan bij het aanmaken van de afbeelding!");
                console.debug(data.message);
                disableNavigateButtons(false);
            }
        });
    }
    
});


/*
 Initialiseren van teken functionaliteit
 Toetslagen laden
 Teken toolbar initialiseren
 queryTask initialiseren
 */
var myErrorHandler = function(e){
    var message = e.message;
    var errorType = "Clientside error: ";
    var details = [];
    
    /*server side errors return a code & possible details*/
    if (e.code) {
        errorType = "Serverside error (" + e.code + "): ";
        details = e.details;
    }
    
    alert(errorType + message + "\n" + details.join("\n"));
}
//window.myErrorHandler = myErrorHandler;

var callCount = 0;


function uploadPlanArea(){
    toggleMapOnly(true);
    disableEventHandlers();
    
    if (AquaWT.planArea === null) 
        AquaWT.planArea = new PlanArea(AquaWT.map, toetsLayerUrl + "/0");
    
    if (AquaWT.planArea) {
        showProgressBar('Uploaden plangebied...');
        AquaWT.planArea.sendIt();
    }
    else {
        alert('Upload kon niet worden geinitialiseerd!');
    };
    }

function jsonToPlanArea(){
    toggleMapOnly(true);
    disableEventHandlers();
    
    var isPlangebied = getInputValue("map_plangebied");
    if(isPlangebied === null || isPlangebied === "") return false;
    
    if (AquaWT.planArea === null) 
        AquaWT.planArea = new PlanArea(AquaWT.map, toetsLayerUrl + "/0");
    
    if (AquaWT.planArea) {
      AquaWT.planArea.addPlanGebiedFromJson();
    }
    else {
        alert('Upload kon niet worden geinitialiseerd!');
    };
    
    return true;
}


function drawPlanArea(){
    // this function will be run when user pushed the draw button.
    
    // first check the scale user is viewing.
    if (!checkScale()) {
        alert(WT_MSG.NIETTEKENEN);
        return;
    }
    
    disableEventHandlers();
    AquaWT.map.graphics.clear();
    
    if (AquaWT.planArea === null) 
        AquaWT.planArea = new PlanArea(AquaWT.map, toetsLayerUrl + "/0");
    AquaWT.planArea.startDrawing();
}

function isGetoetst(){
    var getoetst = false;
    if (AquaWT.planArea) {
        getoetst = AquaWT.planArea.isPlanAreaChecked();
    }
    
    return getoetst;
}

function checkPlanArea(){
    // this function checks is the area is drawn on the map.
    if(AquaWT.planArea === null || AquaWT.planArea._planGebied === null) {
        alert('Nog geen plangebied ingetekend');
        return;
    };

    if (AquaWT.planArea) {
        if (AquaWT.planArea._isDrawing) {
            alert('Sluit eerst de tekenfunctie af met een dubbelklik!');
            return;
        }

        if (AquaWT.planArea._planGebied !== null) {
          // Added line below tot hide the window with the map button's (dashboard)
          toggleElement("infoDiv", false);
          AquaWT.planArea.checkPlanArea()
        }
    }
    
}

function zoomPlanGebied(){
    if (AquaWT.planArea) {
        AquaWT.planArea.zoomPlanArea();
    }
    else {
        alert('Nog geen plangebied ingetekend');
    };
}

/**
 *  Class PlanArea definieert het plangebied. 
 */
dojo.declare("PlanArea", null, {
    _planGebied: null,
    _geometry : null,
    _planGebiedArea: null,
    _editLayer: null,
    _queryTaskWatertoets: null,
    _queryWaterschapBelang: null,
    _map: null,
    _drawToolBar: null,
    _drawHandle: null,
    _wsId: null,
    _waterschap: null,
    _searchWS: null,
    _searchCM: null,
    _queryHandle: null,
    _toetsPlanHandle: null,
    _searchCMHandle: null,
    _gemeente: null,
    _gpBepaalKaartlagen: null,
    _gphandle: null,
    _gpUploader: null,
    _callCount: 0,
    _ioResponse: null,
    _exeConnect: null,
    _isDrawing: false,
    _planGebiedGetoetst: false,
    _numberOfTries : 0,
    _mapmousedownhandle : null,
    _geometryInWSHandle : null,
    _calculateAreaHandle : null,
    _checkLevelHandle: null,
    
    constructor: function(map, layerUrl){
        this._map = map;
        // Set up query tasks
        this._queryTaskWatertoets = new esri.tasks.QueryTask(layerUrl);
        
        // Query voor watertoets
        this._queryWaterschapBelang = new esri.tasks.Query();
        this._queryWaterschapBelang.returnGeometry = false;
        this._queryWaterschapBelang.spatialRelationship = esri.tasks.Query.SPATIAL_REL_INTERSECTS;
        
        this._editLayer = map.graphics;
        this.createDrawToolbar();
        this._numberOfTries = 0;

    },
    
    createDrawToolbar: function(){
        this._drawToolbar = new esri.toolbars.Draw(this._map);
        this._drawHandle = dojo.connect(this._drawToolbar, "onDrawEnd", dojo.hitch(this, this.addToMap));
    },
    
    addToMap: function(geometry){
        // Symbol voor plangebied
        this.stopDrawing();
        this._geometry = geometry;
        
        // check of geometry in een deelnemde waterschap valt
        this._geometryInWSHandle = dojo.subscribe(GEOMETRYINWATERSCHAP, this, "addPlanGebied");
        zoomToGeometryInDeelnemendeWaterschap(geometry, false);
    },

    addPlanGebied : function () {
      if(isInWaterschap) {
        console.debug("addPlanGebied");
        var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NONE, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]));
        this._planGebied = new esri.Graphic(this._geometry, symbol);
        
        this.getArea();
      }
      //dojo.unsubscribe(GEOMETRYINWATERSCHAP);
      dojo.unsubscribe(this._geometryInWSHandle);
      this._geometryInWSHandle = null;
    },

    addPlanGebiedFromJson : function() {
      var JSONText = getInputValue("map_plangebied");
      if (JSONText !== null && JSONText !== "") {
        var jsonObj = dojo.fromJson(JSONText);

        var geometry = new esri.geometry.Polygon(jsonObj);
        this.addToMap(geometry);
        //this.zoomPlanArea();
        
        console.debug("addPlanGebiedFromJson uitgevoerd");
      }
    },
    
    startDrawing: function(){
      if (this._editLayer.graphics.length > 0) {
          if (!confirm('Huidige intekening wordt verwijderd')) 
              return;
      }
      
      this.removeDrawing();
      this._drawToolbar.activate(esri.toolbars.Draw.POLYGON);
      this._map.hideZoomSlider();
      this._isDrawing = true;
      this._planGebiedGetoetst = false;
      dojo.style(dojo.byId("mapDiv"), "cursor", "crosshair");

      msgBox.setMessage("Teken een plangebied met minimaal 3 zijden. <br/>Beëindig met dubbelklikken.<br/><br/>LET OP! Teken het plangebied zo exact mogelijk in, omdat het van invloed kan zijn op de uitkomst van de watertoets.");
      
      disableControls();
      //if(typeof overviewMapDijit !== 'undefined') overviewMapDijit.destroy();
    },
    
    getArea: function(){
        if (this._planGebied === null) 
            return;
        
        var planGebied = [];
        planGebied.push(this._planGebied);
        
        this._calculateAreaHandle = dojo.subscribe(CALCULATE_AREA_READY,this,"setArea");
        
        var geometryServiceTask = new esri.tasks.GeometryService(geometryServiceUrl);
        geometryServiceTask.areasAndLengths(planGebied, dojo.hitch(this, function(areasAndLengths){
            this._planGebiedArea = Math.round(areasAndLengths.areas[0], 1);
            dojo.publish(CALCULATE_AREA_READY);
        }));
    },

    setArea : function() {
      dojo.unsubscribe(this._calculateAreaHandle);

      if (this._planGebiedArea >= MIN_PLANAREA) {
        msgBox.setMessage('&nbsp;<br/>het ingetekende gebied is:<br/>'+ this._planGebiedArea + 'm&sup2; in oppervlakte');
        
        setInputValue('plan_oppervlak', this._planGebiedArea);
        this._editLayer.add(this._planGebied);
        
        this.zoomPlanArea();
        
        var jsonGeometry = dojo.toJson(this._geometry.toJson(), false);
        setInputValue('map_plangebied', jsonGeometry);
        
        return true;
      }
      else {
        alert("Het ingetekende plangebied is te klein!");
        return false;
      }
    },

    
    stopDrawing: function(){
        //this._map.setMapCursor("default"); //1.5 functionaliteit (helaas zit in1.5 een storende bug: tekenen van polygonen met 1 edge))
        dojo.style(dojo.byId("mapDiv"), "cursor", "default");
        
        this._drawToolbar.deactivate();
        this._map.showZoomSlider();
        this._isDrawing = false;

        msgBox.setMessage("");
        enableControls();
        //createOverviewMap();
    },
    
    removeDrawing: function(){
        this._map.graphics.clear();
        this._planGebied = null;
        this._planGebiedArea = null;
        this._planGebiedGetoetst = false;
        this._geometry = null;

        setInputValue('plan_oppervlak',"");
        setInputValue('map_plangebied',"");
        
        msgBox.clear();
    },
    
    
    //***********************************************************************************************
    // Upload functionaliteit
    // 
    sendIt: function(){
        this.removeDrawing();
        var form = dojo.byId("uploadForm");
        form.action = "aquagis/upload/UploadForm.aspx";
        
        dojo.io.iframe.send({
            form: form,
            handleAs: "html",
            
            content: {
                fileFields: "uploadFile"
            },
            
            handle: dojo.hitch(this, function(response, ioArgs){
                if (response instanceof Error) {
                    console.debug("Request FAILED: ", response, ioArgs);
                    this.showerror(response, ioArgs);
                }
                else {
                    console.debug("Request complete: ", response);
                    this.gpResults(response);
                }
            })
        });
    },
    
    showerror: function(response, ioArgs){
        hideProgressBar();
        console.debug('Upload afgebroken: ' + response);
        alert('Het uploaden is afgebroken!');
    },
    
    gpResults: function(response){
        var htmlFile = response;
        var uploadFile = htmlFile.getElementById('zipfile').innerHTML;
        if (uploadFile === null || uploadFile === '') {
            this.showError('Het zipbestand kon niet worden geupload.');
        }
        this._gpUploader = new esri.tasks.Geoprocessor(gpUploaderUrl + "/UploadShapefile");
        
        var theFile = new esri.tasks.DataFile();
        theFile.url = uploadDataLocation + uploadFile;
        console.debug(theFile.url);
        
        var params = {
            "Upload": theFile
        };
        this._gpUploader.execute(params, dojo.hitch(this, this.displayResults), dojo.hitch(this,this.errorResults));
    },
    
    disconnectHandle: function(handle){
        if (handle !== null) {
            dojo.disconnect(handle);
            handle = null;
        }
    },
    
    /*
     * Geef een melding wanneer de uploadservice een fout heeft teruggegeven.
     */
    errorResults: function(error) {
        if (this._numberOfTries < 3) {
          console.debug("Fout bij het uploaden, poging: " + this._numberOfTries);
          this._numberOfTries++;
          this.sendIt();
        }
        else {
          hideProgressBar();
          console.debug("Fout bij het uploaden: " + error);
          alert(WT_MSG.ERRORUPLOAD);
        }
    },
    
    /*
     * Haal de polygoon uit de results en toon deze op het scherm. 
     */
    displayResults: function(results, messages){
        console.debug("displayResults, #result: ");
        console.debug("displayResults, #result: " + results.length + " #messages: " + messages.length);
        
        // Draw results
        var polySymbol = new esri.symbol.SimpleFillSymbol();
        var features = [];
        
        for (var i = 0, rl = results.length; i < rl; i++) {
            if (results[i].paramName === 'OutputFeatureClass') {
                features = results[i].value.features;
            }
            else {
                console.debug(results[i].paramName + ': ' + results[i].value);
            }
        }
        
        hideProgressBar();
        
        if (features.length > 0) {
            console.debug("Retrieve feature from results");
            var feature = features[0];
            this.addToMap(feature.geometry);
            this.zoomPlanArea();
        }
        else {
            for (var m = 0, ml = messages.length; m < ml; m++) {
                console.debug("Fout bij uploaden, messages: ");
                description = messages[m].description;
                console.debug(description);
            }
            
            alert(WT_MSG.ERRORUPLOAD);
        }
    },
    // Einde upload functionaliteit


    // Zoom naar plangebied. Maximaal op 1:5000 in/uitzoomen. 
    // Indien plangebied niet past wordt verder uitgezoomd.    
    zoomPlanArea: function(){
        var EXPAND_FACTOR = 2.0;

        if (this._planGebied) {
          var extent = this._planGebied.geometry.getExtent();
          extent.expand(EXPAND_FACTOR);
          
          this.setLevel(SNAPSHOT_SCALE_LEVEL,extent)
        }
        
    },
    
    setLevel: function(level,planGebiedExtent) {
      var ext = this._setLevel(level,planGebiedExtent.getCenter());
      
      while(level >= 0 && (ext.getWidth() < planGebiedExtent.getWidth() || ext.getHeight() < planGebiedExtent.getHeight() )) {
        level = level-1;
        ext = this._setLevel(level,planGebiedExtent.getCenter());
      }
      
      if (ext) {
        this._map.setExtent(ext);
      }
    },
    
    _setLevel: function(level,pcenter) {
      var ti = this.getTileInfo();
      var center = pcenter || this._map.extent.getCenter();
      if (ti) {
        var lods = ti.lods;
        if (level < 0 || level >= lods.length) {
          return;
        }
        var lod = lods[level];
        var newWidth = this._map.width * lod.resolution / 2;
        var newHeight = this._map.height * lod.resolution / 2;
        return new esri.geometry.Extent(center.x - newWidth, center.y - newHeight, center.x + newWidth, center.y + newHeight, center.spatialReference);
      } else {
        return this.extent.expand(level).centerAt(center);
      }
    },

    getTileInfo: function() {
      var layer = this._map.getLayer(TOP10NL);
      return(layer.tileInfo);  
    },
    
    isPlanAreaChecked: function(){
        console.debug("Getoetst: " + this._planGebiedGetoetst);
        return this._planGebiedGetoetst;
    },
    
    checkPlanArea: function(){
        if (this._isDrawing) 
            this.stopDrawing();
        
        if (this._planGebied === null) {
            alert("Geen plangebied getekend");
            console.debug("Geen plangebied getekend");
            return;
        }
        this.zoomPlanArea();
        showProgressBar('Toetsen plangebied...');
        
        // Externe functie
        executeWatertoets(this._planGebied);
    }
});


/*
 * Schaalbalk functionaliteit
 */

/*
 * Update de schaalbalk tekst met een afgeronde schaal. 
 */
function getNormalizedScale() {
  var currentScale = getScale();  
  var normscales = [50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10];
  var normscale = 100000;
  var dif = 100000;

  for(var i=0; i < normscales.length; i++) {
    var testdif = Math.abs(currentScale - normscales[i]);
    if(testdif < dif) {
      dif = testdif;
      normscale = normscales[i];
    }
  }
  
  return normscale;
}

function updateLegenda() {
  // Normaliseer de schaal
  if(AquaWT.map === null) return false;

  var legendaDiv = dojo.byId("legenda_inside");
  var legendaTekst = dojo.byId("legenda_tekst");
  legendaTekst.style.visibility = 'visible';

  // Is dit nodig?
  dojo.removeClass(legendaDiv,'legenda_0');
  dojo.removeClass(legendaDiv,'legenda_1');
  dojo.removeClass(legendaDiv,'legenda_2');
  dojo.removeClass(legendaDiv,'legenda_3');

  console.log(AquaWT.map.getLevel()); 
  
  var level = AquaWT.map.getLevel();
  // 2000000,1000000,500000,250000,100000,50000
  var TOP250level = 2;   // 500000,100000,
  var TOP50level = 4;    // 100000,50000,25000
  var TOP10level = 6;    // 10000,5000,2500,1000
  
  if(level < TOP250level) {
    console.debug('legenda_0');
    dojo.addClass(legendaDiv,'legenda_0');
    legendaTekst.style.visibility = 'hidden';
  }
  else if(level >= TOP250level && level < TOP50level) {
    console.debug('legenda_1');
    dojo.addClass(legendaDiv,'legenda_1');
  }
  else if(level >= TOP50level && level < TOP10level) {
    console.debug('legenda_2');
    dojo.addClass(legendaDiv,'legenda_2');
  }
  else {
    console.debug('legenda_3');
    dojo.addClass(legendaDiv,'legenda_3');
  }
  
}




/*
 * Pas de schaalbalk aan met het geupdate schaalniveau
 * onExtendChange event Handler
 */
function updateScaleBar() {
  // Normaliseer de schaal
  var scale = getNormalizedScale();
  
  // Bererken de nieuwe breedte van de schaalbalk
  var newWidth = getScalebarWidth(scale);

  // Set de nieuwe schaaltekst
  var tekst = (scale >= 1000) ? (scale/1000 + ' km') : (scale + ' m') ;
  var scaleBarEl = dojo.byId('scalebarDiv');
  if (scaleBarEl) {
    scaleBarEl.innerHTML = tekst;
    scaleBarEl.style.width = newWidth+'px';
    console.log('scale: ' + scale + ' width: ' + newWidth);
  }
}

function getScalebarWidth(scale) {
  if (AquaWT.map === null) 
    return;
    
  var testScale = new esri.geometry.Extent(1, 1, scale, scale);
  var screenGeometry = esri.geometry.toScreenGeometry(AquaWT.map.extent, AquaWT.map.width, AquaWT.map.height, testScale);
  
  return Math.round(screenGeometry.getWidth(), 2);
}

function getScale(){
  if (AquaWT.map === null) 
    return;
    
  var testScale = new esri.geometry.Extent(0, 0, 99, 99);
  var mapGeometry = esri.geometry.toMapGeometry(AquaWT.map.extent, AquaWT.map.width, AquaWT.map.height, testScale);
  
  return Math.round(mapGeometry.getWidth(), 2);
}

function getScaleTekst() {
  //var scale = getScale()/100;
  var tekst = "";//' 1 beeldpunt = ' + scale + ' meter. ';
  
  if(!checkScale) {
    tekst += " Deze schaal is te onnauwkeurig om te tekenen. U moet ingezoomd zijn op schaal 1:" + DRAW_SCALE_ALLOWED;
    tekst += " Gebruik de zoomschuifbalk linksonder, de plus knop in de toolbar rechtsboven of het muiswieltje om verder in te zoomen."
    console.log(tekst); 
  }

  return tekst;
}

function checkScale() {
  if(AquaWT.map === null) return false;

  console.log(AquaWT.map.getLevel() +" - "+ DRAW_SCALE_LEVEL); 
  
  if(AquaWT.map.getLevel() < DRAW_SCALE_LEVEL) {
    return false;
  }
  
  return true;
}

/*
 * Teken de schaalbalk
 */
function getScaleBarShape() {
  // Justificatie vlaggen
  // Zie ook ImageAnnotator.cs class
  var LEFT = 0;
  var CENTRE = 1;
  var RIGHT = 2;
  
  var scale = getNormalizedScale();
  var newWidth = getScalebarWidth(scale);

  var tekst = (scale >= 1000) ? (scale/1000 + ' km') : (scale + ' m') ;
  var mapElementDiv = dojo.byId(AquaWT.map.id);
  var mapHeight = mapElementDiv.clientHeight;
  var mapWidth = mapElementDiv.clientWidth;
  console.debug("Mapwidth: " + mapWidth + " mapHeight: " + mapHeight);
  
  // Schaalbalk rechtsonder in de hoek
  var p1x = mapWidth - 10 - newWidth;
  var p1y = mapHeight - 20;
  
  var p2x = p1x;
  var p2y = (p1y + 10);
  
  var p3x = (p1x + newWidth);
  var p3y = p2y;
  
  var p4x = p3x;
  var p4y = p1y;
   
  var shape = "M " + p1x + " " + p1y + " L " + p2x + " " + p2y + " " + p3x + " " + p3y + " " + p4x + " " + p4y;
  
  var ptx = Math.round(p1x + newWidth/2);
  var pty = p2y;
  var scaletekst = tekst + ";" + ptx + "," + pty + ";" + CENTRE;

  // Disclaimer linksonder in de hoek  
  var discX = 10;
  var discY = mapHeight - 10;  
  var disclaimer = DISCLAIMERTEXT + ";" + discX + "," + discY + ";" + LEFT;
   
  return [shape,scaletekst,disclaimer];     
}



console.debug("Watertoets: watertoets_tekenplan loaded");

/** EOF **/

