function WWLayout() {

  //-------------------
  // Globale Variablen
  //-------------------

  // später checken, ob diese Variablen alle noch gebraucht werden:
  var inWidth  = 0;
  var inHeight = 0;
  var widthAll = 0;
  var widthSidebar = 0;
  var widthMap  = 0;
  var heightMap = 0;
  var heightSidebar = 0;
  var minY = 0; // Grenze, ab der CheckClose...() bei Mausbewegung nach oben (z.B. zum Browsermenü) ein Schließen bewirkt

  var countTranslate = 0;

  var strBackgroundColor = "#FFFEFB"; //"#FFFEFB";

  //--------------------------
  // Write Log
  //--------------------------
  this.WriteLog = function(msg, prio) {
    if (wwParam.prioLog >= prio) {
      console.info(msg);
    }
  }

  //-------------------------------------------------
  // Download und Piwik Tracker
  //-------------------------------------------------
  this.downloadFile = function(url) {
    window.open(url, '_blank');
    _paq.push(['trackLink', url, 'download']);
  }

  //-------------------------------------------------
  // Links und Einstellungen um Karte herum einfügen
  //-------------------------------------------------
  this.InitElementsAroundMap = function() {
    $(document).observe('mousedown', function(event) {
      var elem = $(event.findElement());
      if (elem.hasAttribute('href') && !elem.hasAttribute('onmousedown')) {
        wwExec.pwkTracker(wwExec.pwkiEvent, 'Click::' + elem.innerHTML, "");
        var href = elem.readAttribute('href');
        if (href.search(/mailto/) == -1 && href != "javascript:void(0)") { // wird nicht ins Log eingetragen, also kann man sich den Aufruf sparen
          wwExec.pwkTracker(wwExec.pwkiEvent, 'Click::' + elem.innerHTML, href);
        }
      }
    });

    AdjustSizes();

    // Webcam selection
    var strHTML = '<nobr><span id="FormWebcamSel" style="background-color:' + strBackgroundColor
                + '; z-index:99; overflow:hidden;">' + strCamSelForm + '</span></nobr>';

    $("wRightAboveMap").innerHTML = strHTML;

    // Infos
    var strHTML = '<nobr>'
                + '<a href="javascript:void(0)" onclick="wwLayout.ShowInfos();return false;" class="cinfoslink" style="background-color:'
                + strBackgroundColor + '";>' + wwLang.strInfos + '</a>'
                + '</nobr><div id="InfosContent" style="background-color:' + strBackgroundColor + '; z-index:99; text-align:left; border:' + infoBorder + 'px solid gray;'
                + ' padding:' + infoPadding + 'px; margin:0px; position:absolute; overflow:auto; display:none;">'
                + '<div style="text-align: right;"><img src="./symbols/m_close.png" onclick="wwLayout.HideInfos();return false;" style="cursor:pointer;"></div>'
                + wwLang.strInfosContent + '</div>';
    $("wInfos").innerHTML = strHTML;

    // Language selection
    var strHTML = '<nobr><span id="srcLanguageSel" style="background-color:' + strBackgroundColor
                + '; z-index:99; overflow:hidden;">' + strLanguageSelForm + '</span></nobr>';
    $("wLanguage").innerHTML = strHTML;

    // Translate
    $('wTranslate').observe('click', function(event) {
      countTranslate++;
      wwExec.pwkTracker(wwExec.pwkiEvent, "&Uuml;bersetzen::" + srcLanguage + "->" + dstLanguage + "::" + countTranslate, "");
    });

    // Map source selection
    var strHTML = '<nobr><span id="srcLanguageSel" style="background-color:' + strBackgroundColor
                + '; z-index:99; overflow:hidden;">' + strMapSelForm + '</span></nobr>';
    $("wMapSource").innerHTML = strHTML;

    // Sidebar
    $("wSidebar").innerHTML   = "";

    // Counterbereich
    if ($("wRightBelowMap")) {
      //$("wRightBelowMap").style.height   = "1px"; // Extra niedrig - es wird dann die Texthöhe unter der Karte verwendet
      var strHTML = '<form name="WebcamSearch" action="javascript:void wwLayout.EvalWebcamSearch();">';
      strHTML    += '&nbsp;<input name="SearchSelText" type="text" size="20" maxlength="30" value="' + wwLang.strSearchWebcams
      strHTML    += '" onclick="wwLayout.clearWebcamSearch(this);" onblur="wwLayout.resetWebcamSearch(this);" style="color:grey"></input>';
      strHTML    += '<input type="button" value="OK" onclick="wwLayout.EvalWebcamSearch();"></form>';
      $("wRightBelowMap").innerHTML = strHTML;
    }
  }

  //------------------------------------
  // clearWebcamSearch
  //------------------------------------
  this.clearWebcamSearch = function(elem) {
    if (elem.value == wwLang.strSearchWebcams) {
      elem.value = "";
      elem.style.color = 'black';
    }
  }

  //------------------------------------
  // resetWebcamSearch
  //------------------------------------
  this.resetWebcamSearch = function(elem) {
    if (elem.value == "") {
      elem.value = wwLang.strSearchWebcams;
      elem.style.color = 'grey';
    }
  }

  //----------------------------
  // Koordinatenanzeige setzen
  //----------------------------
  this.SetCoordinates = function(lat, lng, zoom) {
    var url = SetURLforPoint(lat, lng);
    var html = '<a href="' + url + '" class="ccoord" title="'
             + wwLang.strKoordinatenTooltipp + '">' + lat + ', ' + lng + ' (' + zoom + ')</a>';
    if (wwParam.bSwapCoord) {
      html = '&nbsp;lng,lat: ' + html;
    } else {
      html = '&nbsp;' + html;
    }
    $("Koordinaten").innerHTML = html;
  }

  //----------------------------
  // URL für Koordinaten
  //----------------------------
  function SetURLforPoint(lat, lng) {
    wwLayout.WriteLog("Set URL for location", 1);

    var locsearch = window.location.search;
    if (locsearch.charAt(0) == '?') {
      locsearch = locsearch.slice(1);
    }

    var params = locsearch.split("&");
    var locsearchNew = '?lat=' + lat + '&lng=' + lng + '&zoom=' + wwMap.GetZoom();

    for (var idx = 0; idx < params.length; idx++) {
      var vals = params[idx].split("=");

      switch (vals[0]) {
        case "center":
        case "zoom":
        case "lat":
        case "lng":
          break;
        default:
          locsearchNew += '&' + params[idx];
          break;
      }
    }

    return (locsearchNew);
  }

  //----------------------------
  // Infos zeigen
  //----------------------------
  this.ShowInfos = function() {
    var pv = new PosValsInfo();
    var form = $("InfosContent");

    //wwExec.pwkTracker(wwExec.pwkiEvent, 'Infos anzeigen', '');  // wird schon bei onmousedown getrackt
    $(form).show();
    form.style.top       =  pv.posY + "px";
    form.style.left      =  pv.posX + "px";
    form.style.width     =  pv.extX + "px";
    form.style.maxHeight =  pv.extY + "px";
  }

  //----------------------------
  // Infos verbergen
  //----------------------------
  this.HideInfos = function() {
    if ($("InfosContent").style.display == "none") return;
    wwExec.pwkTracker(wwExec.pwkiEvent, 'Click::HideInfos', "");
    $("InfosContent").hide();
  }

  //----------------------------
  // Infos positionieren
  //----------------------------
  var infoPadding = 10;
  var infoBorder  = 1;
  function PosValsInfo() {
    this.dist = 26;
    this.posX = this.dist;
    this.posY = this.dist;
    this.extX = inWidth  - 2 * this.dist - 2 * infoPadding - 2 * infoBorder;
    this.extY = heightMap - 2 * infoPadding - 2 * infoBorder;

    if (this.extX > 900) {
      this.extX = 900;
      this.posX = (inWidth - this.extX) / 2;
    }

    if (self.pageYOffset) { // all except Explorer
      this.posY += self.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
      this.posY += document.documentElement.scrollTop;
    }
    else if (document.body) { // all other Explorers
      this.posY += document.body.scrollTop;
    }
  }


  //-------------------------------------------------
  // Webcam Auswahl
  //-------------------------------------------------

  var strCamSelForm = '<form name="CamSelForm" action="">';
  strCamSelForm    += '';
  strCamSelForm    += '  <select name="selWebcams" size="1" style="background-color:' + strBackgroundColor;
  strCamSelForm    += ';" onchange="wwLayout.EvalWebcamSelection(this);">';
  strCamSelForm    += '    <option value="Null">-- '  + wwLang.strWebcamSelection + ' --</option>';
  if (showWebcams == "NewCams") {
    strCamSelForm    += '    <option value="NewCams" selected>'  + wwLang.strShowNewWebcams + '</option>';
  } else {
    strCamSelForm    += '    <option value="NewCams">'  + wwLang.strShowNewWebcams + '</option>';
  }
  if (showWebcams == "Day") {
    strCamSelForm    += '    <option value="Day" selected>'  + wwLang.strShowDaylightWebcams + '</option>';
  } else {
    strCamSelForm    += '    <option value="Day">'  + wwLang.strShowDaylightWebcams + '</option>';
  }
  if (showWebcams == "DayTwi") {
    strCamSelForm    += '    <option value="DayTwi" selected>'  + wwLang.strShowDayTwiWebcams + '</option>';
  } else {
    strCamSelForm    += '    <option value="DayTwi">'  + wwLang.strShowDayTwiWebcams + '</option>';
  }
  if (showWebcams == "Twilight") {
    strCamSelForm    += '    <option value="Twilight" selected>'  + wwLang.strShowTwilightWebcams + '</option>';
  } else {
    strCamSelForm    += '    <option value="Twilight">'  + wwLang.strShowTwilightWebcams + '</option>';
  }
  if (showWebcams == "Night") {
    strCamSelForm    += '    <option value="Night" selected>'  + wwLang.strShowNightWebcams + '</option>';
  } else {
    strCamSelForm    += '    <option value="Night">'  + wwLang.strShowNightWebcams + '</option>';
  }
  //if (camsVideo == "Video") {
    //strCamSelForm    += '    <option value="Video" selected>'  + wwLang.strShowVideo + '</option>';
  //} else {
    //strCamSelForm    += '    <option value="Video">'  + wwLang.strShowVideo + '</option>';
  //}
  //if (camsVideoAudio == "VideoAudio") {
    //strCamSelForm    += '    <option value="VideoAudio" selected>'  + wwLang.strShowVideoWithSound + '</option>';
  //} else {
    //strCamSelForm    += '    <option value="VideoAudio">'  + wwLang.strShowVideoWithSound + '</option>';
  //}
  strCamSelForm    += '  </select> ';
  strCamSelForm    += '  </form> ';

  //-------------------------------------------------
  // Webcam Auswahl verarbeiten
  //-------------------------------------------------
  var showWebcams;
  this.EvalWebcamSelection = function() {
    //*** Log hinzufügen (auch bei weiteren Funktionen in dieser Datei)

    var selWebcams = document.CamSelForm.selWebcams;
    var showWebcamsNew = selWebcams.options[selWebcams.selectedIndex].value;

    var selWebcam = "AllCams";
    var selTime   = "AllCams";
    switch (showWebcamsNew) {
      case "NewCams":
        selWebcam = showWebcamsNew;
        break;
      case "Day":
      case "DayTwi":
      case "Twilight":
      case "Night":
        selTime = showWebcamsNew;
        break;
      default:
        break;
    }

    var str = "Webcam Auswahl::" + showWebcamsNew;
    wwExec.pwkTracker(wwExec.pwkiEvent, str, '');
    wwExec.FilterSidebar("AllCams", "", selWebcam, "AllCams", selTime);
  }

  //-------------------------------------------------
  // Webcam Suche verarbeiten
  //-------------------------------------------------
  var showWebcams;
  this.EvalWebcamSearch = function() {
    var searchWebcams = document.WebcamSearch.SearchSelText.value;
    var str = "Webcam Suche::" + searchWebcams;
    wwExec.pwkTracker(wwExec.pwkiEvent, str, '');
    wwExec.FilterSidebar("SearchSel", searchWebcams, "AllCams", "AllCams", "AllCams");
  }


  //-------------------------------------------------
  // MapSource Auswahl
  //-------------------------------------------------
  var strMapSelForm = '<form name="MapSourceSelForm" action="index.php">';
  strMapSelForm    += '  <select name="selMapSource" size="1" style="background-color:' + strBackgroundColor;
  strMapSelForm    += ';" onchange="wwLayout.EvalMapSourceSelection(this);">';
  //strMapSelForm    += '   <optgroup label="' + wwLang.strSettingsSelectMap + '">';
  if (mapSource == "nomap") {
    strMapSelForm    += '    <option value="nomap" selected>'  + wwLang.strSettingsNoMap + '</option>';
  } else {
    strMapSelForm    += '    <option value="nomap">'  + wwLang.strSettingsNoMap + '</option>';
  }
  //strMapSelForm    += '    <option value="gmap2">'  + wwLang.strSettingsGMap2 + '</option>';
  if (mapSource == "gmap3") {
    strMapSelForm    += '    <option value="gmap3" selected>'  + wwLang.strSettingsGMap3 + '</option>';
  } else {
    strMapSelForm    += '    <option value="gmap3">'  + wwLang.strSettingsGMap3 + '</option>';
  }
  if (mapSource == "ymap") {
    strMapSelForm    += '    <option value="ymap" selected>'   + wwLang.strSettingsYMap  + '</option>';
  } else {
    strMapSelForm    += '    <option value="ymap">'   + wwLang.strSettingsYMap  + '</option>';
  }
  if (mapSource == "mmap") {
    strMapSelForm    += '    <option value="mmap" selected>'   + wwLang.strSettingsMMap  + '</option>';
  } else {
    strMapSelForm    += '    <option value="mmap">'   + wwLang.strSettingsMMap  + '</option>';
  }
  //strMapSelForm    += '   </optgroup>';
  //strMapSelForm    += '   <optgroup label="Google Earth">';
  //strMapSelForm    += '    <option value="gearth" title="' + wwLang.strLastModified + '">' + wwLang.strSettingsGEarth  + '</option>';
  strMapSelForm    += '    <option value="gearth" title="' + wwLang.strLastModified + '">' + wwLang.strViewInGoogleEarth  + '</option>';
  //strMapSelForm    += '   </optgroup>';
  strMapSelForm    += '  </select> ';
  strMapSelForm    += '  </form> ';


  //-------------------------------------------------
  // MapSource Auswahl verarbeiten
  //-------------------------------------------------
  this.EvalMapSourceSelection = function(select) {
    var selMapSource = document.MapSourceSelForm.selMapSource;
    var mapSourceNew = selMapSource.options[selMapSource.selectedIndex].value;

    wwExec.pwkTracker(wwExec.pwkiEvent, 'MapSource Auswahl::' + mapSourceNew, '');

    if (mapSourceNew == mapSource) return;

    if (mapSourceNew == "gearth") {
      wwLayout.downloadFile(wwLang.strUrlGoogleEarthFile);
      return;
    }

    var locsearch = window.location.search;
    if (locsearch.charAt(0) == '?') {
      locsearch = locsearch.slice(1);
    }

    var params = locsearch.split("&");
    var locsearchNew = '?map=' + mapSourceNew;

    for (var idx = 0; idx < params.length; idx++) {
      var vals = params[idx].split("=");

      switch (vals[0]) {
        case "map":
          break;
        default:
          locsearchNew += '&' + params[idx];
          break;
      }
    }

    window.location.href = window.location.pathname + locsearchNew;
  }

  //-------------------------------------------------
  // Positionswerte für Sprachauswahl
  //-------------------------------------------------
  function PosValsLanguageSel() {
    this.dist = 8;
    this.extX = 300;
    this.extY = heightMap;
    this.posX = widthMap / 2 - this.extX / 2 + this.dist; // + this.dist wegen Abstand am linken Fensterrand
    this.posY = 21;
  }

  //-------------------------------------------------
  // Sprachauswahl
  //-------------------------------------------------

  var strLanguageSelForm = '<form name="LanguageSelForm" action="index.php">';
  strLanguageSelForm    += '  <select name="srcLang" size="1" style="background-color:' + strBackgroundColor;
  strLanguageSelForm    += ';" onchange="wwLayout.srcLanguageSelection(this);">';
  if (srcLanguage == "de") {
    strLanguageSelForm    += '    <option value="de" selected>'    + wwLang.strSettingsGerman        + '</option>';
    strLanguageSelForm    += '    <option value="en">'    + wwLang.strSettingsEnglish       + '</option>';
  } else {
    strLanguageSelForm    += '    <option value="de">'    + wwLang.strSettingsGerman        + '</option>';
    strLanguageSelForm    += '    <option value="en" selected>'    + wwLang.strSettingsEnglish       + '</option>';
  }
  strLanguageSelForm    += '  </select> ';
  //strLanguageSelForm    += '<span style="font-weight:bold;">&#x21E8;</span>';
  strLanguageSelForm    += '<span style="font-weight:bold;">=></span>';
  strLanguageSelForm    += '  <select name="dstLang" size="1" style="background-color:' + strBackgroundColor;
  strLanguageSelForm    += ';" onchange="wwLayout.dstLanguageSelection(this);">';
  wwLang.hLang.each(function(pair) {
    var lang = pair.key;
    if (lang == "zhTW") lang = "zh-TW";
    if (lang == "zhCN") lang = "zh-CN";
    if (lang == dstLanguage) {
      strLanguageSelForm  += '  <option value="' + lang + '" selected>' + pair.value + '</option>';
    } else {
      strLanguageSelForm  += '  <option value="' + lang + '">' + pair.value + '</option>';
    }
  });
  strLanguageSelForm    += '  </select>';
  strLanguageSelForm    += '</form>';

  //-------------------------------------------------
  // Sprachauswahl verarbeiten
  //-------------------------------------------------

  var srcLanguageNew = srcLanguage;
  this.srcLanguageSelection = function(ev) {
    var srcLang = document.LanguageSelForm.srcLang;
    srcLanguageNew = srcLang.options[srcLang.selectedIndex].value;
    loadNewLanguage();
  }

  var dstLanguageNew = dstLanguage;
  this.dstLanguageSelection = function(ev) {
    var dstLang = document.LanguageSelForm.dstLang;
    dstLanguageNew = dstLang.options[dstLang.selectedIndex].value;
    loadNewLanguage();
  }

  function loadNewLanguage() {
    var locsearch = window.location.search;
    if (locsearch.charAt(0) == '?') {
      locsearch = locsearch.slice(1);
    }

    var params = locsearch.split("&");
    var locsearchNew = '?sl=' + srcLanguageNew;
    locsearchNew    += '&dl=' + dstLanguageNew;

    for (var idx = 0; idx < params.length; idx++) {
      var vals = params[idx].split("=");

      switch (vals[0]) {
        case "sl":
        case "lang": // alter Parameter
        case "dl":
          break;
        default:
          locsearchNew += '&' + params[idx];
          break;
      }
    }

    window.location.href = window.location.pathname + locsearchNew;
  }


  //-----------------------------------------------------------
  // Fenstergröße ermitteln (gleiche Funktion wie in WWSun)
  //-----------------------------------------------------------
  function GetInnerSize() {
    if (self.innerHeight) // all except Explorer
    {
      inWidth = self.innerWidth;
      inHeight = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode
    {
      inWidth = document.documentElement.clientWidth;
      inHeight = document.documentElement.clientHeight;
    }
    else if (document.body) // other Explorers
    {
      inWidth = document.body.clientWidth;
      inHeight = document.body.clientHeight;
    }
  }

  //--------------------------------------
  // Größenwerte an Fenstergröße anpassen
  //--------------------------------------
  function SetSizeVals() {
    GetInnerSize();

    widthAll     = inWidth - 30;
    widthSidebar = 280;

    widthMap  = inWidth - widthSidebar;
    heightMap = inHeight - 64;

    //heightSelMarker = 60;
    heightSidebar   = heightMap; // - heightSelMarker;
  }

  //------------------------------------------
  // Größenwerte auf die Darstellung anwenden
  //------------------------------------------
  function AdjustSizes() {
    SetSizeVals();
    $("wInfos").style.width     = (widthMap / 3)  + "px";
    $("wLanguage").style.width  = (widthMap / 3)  + "px";
    $("wMapSource").style.width = (widthMap / 3)  + "px";

    $("wMap").style.width  = widthMap  + "px";
    $("wMap").style.height = heightMap + "px";
    if (mapSource == "nomap") {
      $("wMap").style.overflow = "auto";
    }
    if (mapSource == "mmap") {
      $("wMap").style.position = "relative";
    }
    //$("wSidebar").style.width  = widthSidebar + "px";
    $("wSidebar").style.height = heightMap + "px";

    // crosshair
    if (mapSource != "nomap") {
      var layout = $('wMap').getLayout();
      var top    = layout.get('top');
      var left   = layout.get('left');
      var width  = layout.get('width');
      var height = layout.get('height');
      var src = './symbols/m_crosshair.png';
      var extX = 15; // Breite der Gafik
      var extY = 15; // Höhe der Grafik
      var posX = left + (width  - extX) / 2;
      var posY = top  + (height - extY) / 2;
      $("crosshair").innerHTML = '<img src="' + src + '" style="position:absolute; top:'
                     + posY + 'px; left:'   + posX + 'px; width:'
                     + extX + 'px; height:' + extY + 'px; z-index:1">';
      crosshairPosX = posX;
      crosshairPosY = posY;
      crosshairExtX = extX;
      crosshairExtY = extY;
    }

    $('crosshair').observe("mousemove", crosshairShowHide);
  }

  var crosshairPosX = 0;
  var crosshairPosY = 0;
  var crosshairExtX = 0;
  var crosshairExtY = 0;
  function crosshairShowHide(ev) {
    var mouseX = ev.pointer().x - document.viewport.getScrollOffsets().left;
    var mouseY = ev.pointer().y - document.viewport.getScrollOffsets().top;
    if (mouseX >= crosshairPosX && mouseX <= crosshairPosX + crosshairExtX && mouseY >= crosshairPosY && mouseY <= crosshairPosY + crosshairExtY) {
      $('wMap').observe("mousemove", crosshairShowHide);
      $('crosshair').hide();
    } else {
      $("wMap").stopObserving("mousemove");
      $('crosshair').show();
    }
  }

  window.onresize = AdjustSizes;

}

var wwLayout = new WWLayout();

