/* Work around missing console object on some browsers. */
if(typeof console == 'undefined') {
  console = {
    assert: function() {},
    count: function() {},
    debug: function() {},
    dir: function() {},
    dirxml: function() {},
    error: function() {},
    groupEnd: function() {},
    group: function() {},
    info: function() {},
    log: function() {},
    profileEnd: function() {},
    profile: function() {},
    timeEnd: function() {},
    time: function() {},
    trace: function() {},
    warn: function() {}
  }
};

var $j = jQuery.noConflict();

var obs = function() {

  var slider = function () {
    function up() {
      var div = $j(this).parents('.slider');
      div.find('.sliderBody').slideUp('normal', function() {
        div.find('.sliderHead').unbind().click(down).find('.sliderButton').unbind().click(down).css('background-image', 'url('+IMGROOT+'/slider_button_down.gif)').blur();
      });
      return false;
    }

    function down() {
      var div = $j(this).parents('.slider');
      div.find('.sliderBody').slideDown('normal', function() {
        div.find('.sliderHead').unbind().click(up).find('.sliderButton').unbind().click(up).css('background-image', 'url('+IMGROOT+'/slider_button_up.gif)').blur();
      });
      return false;
    }

    function init(id) {
      var selector = '.slider';
      if(typeof(id) == 'string') {
        var selector = '#' + id + ' ' + selector;
      }
      $j(selector).find('.sliderHead').click(down).find('.sliderButton').click(down);
    }

    return {
      init: init
    };
  }();

  function initExternalLinks() {
    $j('a.external').click(function() {
      window.open($j(this).attr('href'));
      return false;
    });
  }

  function initNavi() {
    /* FIXME better set outline style? */
    $j('#navigation a').focus(function() {
      this.blur();
    });
  }

  function initAutosubmit() {
    $j('select.autosubmit').change(function() {
      $j(this).parents('form').get(0).submit();
    });
  }

  function initPrintButton() {
    $j('.printButton').click(function() {
      window.print();
      return false;
    });
  }

  function initReloadButton() {
    $j('button.pageReload').click(function() {
      window.location.reload();
    });
  }

  function initSettingsBox() {
    $j('a.buttonSaveSettings').click(function() {
      var url = $j(this).attr('href');
      var id = $j(this).parents('.settingsBox').attr('id');
      var data = $j('#'+id).parents('form').formToArray();
      obs.startLoading(id, __('savingSettings'));
      $j.post(
        url,
        data,
        function(data) {
          obs.endLoading(id);
        }
      );
      return false;
    })
  }

  function initPopupHelp() {
    $j('#helpPopupLink, #helpPopupLinkImage').click(function() {
      /* same name as in minidat */
      var helpWindow = window.open(this.href, 'hilfefenster', "dependent=yes,resizable=yes,scrollbars=yes,width=500,height=700,left=500,top=200");
      helpWindow.focus();
      return false;
    });
  }

  function initPopupATS() {
    $j('#ATSPopupLink, #ATSPopupLinkImage').click(function() {
      /* same name as in minidat */
      var ATSWindow = window.open(this.href, 'ATSfenster', "dependent=yes,resizable=yes,scrollbars=yes,width=500,height=700,left=500,top=200");
      ATSWindow.focus();
      return false;
    });
  }

  function initButtonAnis() {
    var currBtn = null;

    $j('button.flatButton, input.submit, button.submit').mousedown(function() {
      currBtn = this;
      $j(this).css('background-position', 'bottom');
      return true;
    }).mouseout(function() {
      if(currBtn == this) {
        $j(currBtn).css('background-position', 'top');
      }
      return true;
    }).mouseover(function() {
      if(currBtn == this) {
        $j(currBtn).css('background-position', 'bottom');
      }
      return true;
    });
    $j('body').mouseup(function() {
      if(currBtn != null) {
        $j(currBtn).css('background-position', 'top');
        currBtn = null;
      }
      return true;
    });
  }

  function init() {
    slider.init();
    obs.deviceSelector.init();
    obs.atsAlert.init();
    initNavi();
    initPopupHelp();
    initButtonAnis();
    initPopupATS();
    initSettingsBox();
    initPrintButton();
    initAutosubmit();
    initReloadButton();
    initExternalLinks();
  }

  var util = {
    startLoading: function(id, html) {
      var indId = 'loadingIndicator_' + id;
      var elem = $j('#'+id)
      var offset = elem.offset();
      var width = elem.width() * .8;
      var height = elem.height();
      var left = offset.left + elem.width() * .1;

      elem.css('visibility', 'hidden');

      $j('body').append('<div id="' + indId + '" class="loadingIndicator"></div>');
      $j('#' + indId).css({
        position: 'absolute',
        visibility: 'hidden'
      });
      $j('#' + indId).html('<img style="float:left; width: auto;" src="'+ IMGROOT + '/loading.gif" /><div style="float:left; width: auto;">'+ html + '</div><br style="clear: both;" />');
      $j('#' + indId).css({
        'width': width + 'px',
        'left': left + 'px'
      });
      var top = offset.top + height / 2 - $j('#' + indId).height() / 2;
      $j('#' + indId).css('top', top + 'px');
      $j('#' + indId).css('visibility', 'visible');
    },

    endLoading: function(id) {
      $j('#loadingIndicator_' + id).remove();
      $j('#'+id).css('visibility', 'visible');
    },

    url_for: function(action) {
      return CONTROLLER + action;
    },

    appendUrlParam: function(url, key, val) {
      return url + ( url.match(/\?/)?'&':'?' ) + key + '=' + val;
    }
  };

  return {
    init: init,
    url_for: util.url_for,
    appendUrlParam: util.appendUrlParam,
    startLoading: util.startLoading,
    endLoading: util.endLoading
  };
}();

obs.deviceSelector = function() {
  var elem;
  var options = {};
  var events = {};
  var emptyLabel = null;
  var emptyChoosable = false;
  var clickTriggeredFocus = false;
  
  var acOptions = {
    /* needed for selectbox like-behavior */
    minLength: 0,
    autoFocus: true,
    delay: 300,
    focus: function(event, ui) {
      $j('#ds_deviceId').val(ui.item.value);
      /*
      if(!clickTriggeredFocus) {
        $j(this).val(ui.item.label);
      }
      */
      clickTriggeredFocus = false;
      return false;
    },
    select: function(event, ui) {
      $j('#ds_deviceId').val(ui.item.value);
      $j(this).val(ui.item.label);
      handleEvent('change');
      saveDeviceSelection(function() {
        handleEvent('changeComplete');
      });
      return false;
    }
  };

  function saveDeviceSelection(success) {
    $j.post(obs.url_for('common/saveDeviceSelection'),
            {
              groupId: elem.find('.ds_machine_group').val(),
              deviceId: elem.find('#ds_deviceId').val()
            },
            function() {
              if(typeof success == 'function') {
                success();
              }
            });
  }

  function handleEvent(type) {
    if(typeof events[type] != 'undefined') {
      /* check for undefined, may be unbound during event handling */
      for(var i = 0; typeof events[type] != 'undefined' && i < events[type].length; i++) {
        events[type][i]();
      }
    }
  }

  function initAutocomplete(extraOptions) {
    $j('input.ds_device')
      .unbind()
      .autocomplete($j.extend({}, acOptions, extraOptions))
      .click(function() {
        clickTriggeredFocus = true;
        var obj = $j(this);
        obj.val('');
        /* give ie some time to redraw the input field. */
        window.setTimeout(function() {
          obj.autocomplete('search', '');
        }, 50);
      });
  }

  function convertSelectbox() {
    var devices = [];
    var label = '';
    var deviceId = '';
    var deviceSelectbox = elem.find('select.ds_device');

    deviceSelectbox.find('option').each(function() {
      if($j(this).is(':selected')) {
        label = $j(this).html();
        deviceId = $j(this).attr('value');
      }
      if($j(this).attr('value') == '') {
        emptyLabel = $j(this).html();
        if(emptyChoosable) {
          devices.push({
            label: $j(this).html(),
            value: $j(this).attr('value')
          });
        }
      } else {
        devices.push({
          label: $j(this).html(),
          value: $j(this).attr('value')
        });
      }
    });
    deviceSelectbox.replaceWith('<input class="ds_device" name="deviceLabel" />');
    $j('input.ds_device').val(label).after('<input id="ds_deviceId" type="hidden" name="deviceId" />');
    $j('#ds_deviceId').val(deviceId);
    initAutocomplete({source: devices});
  }

  function groupChanged() {
    elem.find('input.ds_device').val(__('deviceSelector_updating'));
    handleEvent('change');

    var url = obs.url_for('common/deviceSelectorOptions');
    for(var key in options) {
      url = obs.appendUrlParam(url, 'options[' + key + ']', options[key]);
    }

    $j.getJSON(url, {group: $j(this).val()}, function(data) {
      if(emptyChoosable) {
        data.unshift({
          label: emptyLabel,
          value: ''
        });
      }
      initAutocomplete({source: data});
      elem.find('input.ds_device').val(emptyLabel);
      elem.find('#ds_deviceId').val('');
      saveDeviceSelection(function() {
        handleEvent('changeComplete');
      });
    });
  }

  function init() {
    elem = $j('.deviceSelector');
    if(elem.length < 1) {
      return;
    }

    options = eval('(' + $j('#deviceSelectorOptions').val() + ')');
    $j('#deviceSelectorOptions').remove();
    emptyChoosable = elem.find('select.ds_device').hasClass('empty_entry_choosable');

    convertSelectbox();

    elem.find('select.ds_machine_group').change(groupChanged);

    if(elem.hasClass('auto')) {
      changeComplete(submitForm);
    }
  }

  function submitForm() {
    $j('.deviceSelector').parents('form').get(0).submit();
  }

  function val(deviceId, groupId) {
    if(typeof groupId == 'undefined' && typeof deviceId == 'undefined') {
      return {
        groupId: elem.find('.ds_machine_group').val(),
        deviceId: elem.find('#ds_deviceId').val()
      };
    }
    if(typeof groupId != 'undefined' && groupId != null) {
      elem.find('.ds_machine_group').val(groupId);
    }
    if(typeof deviceId != 'undefined' && deviceId != null) {
      elem.find('.ds_device').val(deviceId);
    }
    handleEvent('change');
    return this;
  }

  function unbind() {
    if(unbind.arguments.length == 0) {
      events = {};
    } else {
      for(var i = 0; i < unbind.arguments.length; i++) {
        events[unbind.arguments[i]] = [];
      }
    }
    return obs.deviceSelector;
  }

  function addEventHandler(name, cb) {
    if(typeof(events[name]) == 'undefined') {
      events[name] = [cb];
    } else {
      events[name].push(cb);
    }
  }

  function change(cb) {
    addEventHandler('change', cb);
    return obs.deviceSelector;
  }

  function changeComplete(cb) {
    addEventHandler('changeComplete', cb);
    return obs.deviceSelector;
  }

  function enable() {
    $j('.deviceSelector select').removeAttr('disabled');
  }

  function disable() {
    $j('.deviceSelector select').attr('disabled', 'disabled');
  }

  return {
    init: init,
    val: val,
    change: change,
    changeComplete: changeComplete,
    unbind: unbind,
    enable: enable,
    disable: disable,
    submitForm: submitForm
  };
}();

obs.connectionManager = function() {
  var xhr = null;
  var timer = null;

  var interval = 0;
  var devices = null;
  var target = null;
  var connectionStatus = [];
  var autoUpdate = false;

  function update(anInterval, theOptions) {
    if(typeof theOptions == 'undefined') {
      theOptions = {};
    }
    var options = theOptions;
    if(typeof anInterval == 'undefined') {
      anInterval = 0;
    }
    var interval = anInterval;

    cancelUpdate();

    autoUpdate = anInterval > 0;
    
    function runUpdate() {
      var url = obs.url_for('common/getConnectionStatus');
      for(i = 0; i < devices.length; i++) {
        url += ((i == 0) ? '?' : '&' ) + 'deviceIds[]=' + devices[i];
      }

      xhr = $j.get(
        url,
        function(data) {
          $j(target).html(data);
          var connectionStatus = eval($j('#connectionStatusJson').val());
          if(connectionStatus.length < 1) {
            $j(target).html('<p>' + __('no_connection') + '</p>');
          }

          /* this must be done before the callbacks are called, since
             they might want to kill the timeout via cancelUpdate() */
          if(interval > 0) {
            timer = window.setTimeout(runUpdate, interval * 1000);
          }

          if(typeof options.afterFirstUpdate == 'function') {
            options.afterFirstUpdate(connectionStatus);
            options.afterFirstUpdate = null;
          }
          if(typeof options.afterUpdate == 'function') {
            options.afterUpdate(connectionStatus);
          }
        }
      );
    }

    runUpdate();
  }

  function cancelUpdate() {
    autoUpdate = false;
    if(timer != null) {
      window.clearTimeout(timer);
      timer = null;
    }
    if(xhr != null && xhr.readyState < 4 /* done */) {
      xhr.abort();
      xhr = null;
    }
  }

  function autoUpdateEnabled() {
    return autoUpdate;
  }

  function setDevices(theDevices) {
    devices = theDevices;
    /* FIXME restart update if neccessary */
  }

  function init(options) {
    devices = options.devices;
    target = '#connectionStatus';
    if((typeof options.target) != 'undefined') {
      target = options.target;
    }
  }

  return {
    init: init,
    update: update,
    setDevices: setDevices,
    cancelUpdate: cancelUpdate,
    autoUpdateEnabled: autoUpdateEnabled
  };
}();

obs.atsAlert = function() {
  var soundLoaded = false;

  function load() {
    var mySound = soundManager.createSound({
      // sound name
      id: 'beep',
      // sound location
      url: WEBROOT+'/js/soundmanager/beep.mp3'
    });
    soundLoaded = true;
  }

  function soundLoop() {
    /* sound might be loaded after document.ready(), so make sure it's there.
       Don't delay it too much, we want to hear the sound as soon as the
       page is loaded. */
    if(!soundLoaded) {
      window.setTimeout(soundLoop, 250);
      return;
    }

    if($j('#atsAlertCount').val() < 1) {
      window.setTimeout(soundLoop, 250);
      return;
    }

    soundManager.play('beep', { volume: 100 });
    window.setTimeout(soundLoop, 5000);
  }

  /* onload must be set in time. */
  function preInit() {
    // directory where SM2 .SWFs live
    soundManager.url = WEBROOT+'/js/soundmanager/swf';
    soundManager.debugMode = false;
    soundManager.onload =  load;
  }

  function updateAlert() {
    if($j('#atsAlertCount').val() > 0) {
      $j('#alarmmeldung').show();
    } else {
      $j('#alarmmeldung').hide();
    }
  }

  function init() {
    if($j('#alarmmeldung').length < 1) {
      return;
    }
    updateAlert();
    soundLoop();
    setInterval(refreshAlarmmeldung, 30000);
  }

  function refreshAlarmmeldung() {
    $j.ajax({
      method: 'get',
      url : CONTROLLER + 'common/alarmmeldung',
      dataType : 'text',
      success: function(text) {
        $j('#alarmmeldung').html(text);
        updateAlert();
      }
    });
  }

  return {
    init: init,
    preInit: preInit
  };
  
}();

obs.cookie = {
  set: function(name, value, expires, path, domain, secure) {
    var today = new Date();
    today.setTime(today.getTime());

    if(expires) {
      expires = expires * 1000 * 60 * 60 * 24;
    }
    var expires_date = new Date( today.getTime() + (expires) );

    document.cookie = name + "=" +escape(value)
      + ((expires) ? ";expires=" + expires_date.toGMTString() : "")
      + ((path) ? ";path=" + path : "")
      + ((domain) ? ";domain=" + domain : "")
      + ((secure) ? ";secure" : "");
  },

  get: function(name) {
    var start = document.cookie.indexOf(name + "=");
    var len = start + name.length + 1;

    if((!start) && (name != document.cookie.substring(0, name.length))) {
      return null;
    }
    if(start == -1) {
      return null;
    }

    var end = document.cookie.indexOf( ";", len);

    if(end == -1) {
      end = document.cookie.length;
    }
    return unescape(document.cookie.substring(len, end));
  },

  del: function(name, path, domain) {
    if(obs.cookie.get(name)) {
      document.cookie = name + "="
        + ((path) ? ";path=" + path : "")
        + ((domain) ? ";domain=" + domain : "" )
        + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
    }
  }
};

$j(obs.init);
obs.atsAlert.preInit();

