var OtosImageUpdater = function ()
{
  return {
    
    start: function (img, interval)
    {
      img.onload = null;
      var src = img.src;
      window.setInterval(function () { OtosImageUpdater.update(img, src); }, interval * 1000);
    },
    
    update: function (img, src)
    {
      var newSrc = src + (src.indexOf("?") == -1 ? "?" : "&uniq=") + (new Date()).getTime();
      img.src = newSrc;
    }
  };
}();

/**
 * Displays the statistics of an area
 *
 * Example usage:
 *
 * <div id="otos"></div>
 * <script type="text/javascript">
 *   new OtosStatistics('00408C850CEE', 2);
 * </script>
 *
 * This creates an iframe with the statistics to an element with id 'otos'.
 * The first parameter is the camera-id and the second parameter is the area-id.
 * The constructor also takes an optional third parameter, which is an object
 * with the following attributes:
 *
 * - parent_id : the id of the container element, default value is 'otos'. if
 *               the container element doesn't exist (or exists later in the
 *               document body), an exception is thrown
 * - scale     : how high the height of the statistics should be compared to the
 *               width. for example, if the width of the statistics component
 *               is 300px and the scale attribute is 0.8, the height will be
 *               300 * 0.8 = 240. the default value is 0.9
 * - width     : the width of the statistics component in pixels. if the value
 *               isn't set, the component tries to match the width of the parent
 *               element
 * - height    : the height of the element. if the height isn't set, it is
 *               calculated using the width of the component and the
 *               scale-attribute
 * - period    : the period of the statistics. possible values are 'hour',
 *               'day' (default), 'week', 'month' and 'year'
 * - date_from : the start date of the statistics, formatted as
 *               YYYY-MM-DD HH:MM:SS
 * - day_offset: the offset, calculated from date_from. if the date_from isn't
 *               set and the value of day_offset is 1, the component displays
 *               the prediction statistics of tomorrow
 * - refresh   : the refresh interval of the statistics component in seconds
 * - chart     : the chart type
 * - stat_type : the type of the statistics
 * - server    : the ip address of the otos-server
 * - styles    : an object with the chart styles (see manual)
 *
 * @param camId the id of the camera
 * @param areaId the area-id
 * @param arguments settings for the statistics
 */
var OtosStatistics = function (camId, areaId)
{
  // define the chart settings
  var config  = arguments[2] || {};
  var server  = !config.server ? 'localhost' : config.server;
  var params  = '&server=' + server + '&cam_id=' + camId + '&area_id=' + areaId;

  new OtosStatisticsFrame(params, config);
};

/**
 * Displays the combination statistics of multiple lines
 *
 * Example usage:
 *
 * <div id="otos"></div>
 * <script type="text/javascript">
 *   new OtosCombinationStatistics([
 *     { server: '10.10.10.201', camera_id: '00408C80AB44', area_id: 9 },
 *     { server: '10.10.10.201', camera_id: '00408C80AB44', area_id: 6 }
 *   ]);
 * </script>
 *
 * This creates an iframe with the statistics to an element with id 'otos'.
 * The first parameter is an array of objects containing information of the
 * lines. The objects have two mandatory key-value -pairs; 'camera_id' and
 * 'area_id' which both should be self-explanatory. The object can also contain
 * the key 'server', which is the ip-address of the server where the cameras are
 * located. The constructor also takes an optional second parameter, which is
 * an object with the following attributes:
 *
 * - parent_id : the id of the container element, default value is 'otos'. if
 *               the container element doesn't exist (or exists later in the
 *               document body), an exception is thrown
 * - scale     : how high the height of the statistics should be compared to the
 *               width. for example, if the width of the statistics component
 *               is 300px and the scale attribute is 0.8, the height will be
 *               300 * 0.8 = 240. the default value is 0.9
 * - width     : the width of the statistics component in pixels. if the value
 *               isn't set, the component tries to match the width of the parent
 *               element
 * - height    : the height of the element. if the height isn't set, it is
 *               calculated using the width of the component and the
 *               scale-attribute
 * - period    : the period of the statistics. possible values are 'hour',
 *               'day' (default), 'week', 'month' and 'year'
 * - date_from : the start date of the statistics, formatted as
 *               YYYY-MM-DD HH:MM:SS
 * - day_offset: the offset, calculated from date_from. if the date_from isn't
 *               set and the value of day_offset is 1, the component displays
 *               the prediction statistics of tomorrow
 * - refresh   : the refresh interval of the statistics component in seconds
 * - chart     : the chart type
 * - styles    : an object with the chart styles (see manual)
 *
 * @param arr The area-objects
 * @param arguments The settings for the statistics
 */
var OtosCombinationStatistics = function (arr)
{
  var config = arguments[1] || {};
  var params = '';

  for (var i = 0; i < arr.length; i++)
  {
    params += '&areas[]=' + (arr[i].server ? arr[i].server : 'localhost') +
      '|' + arr[i].camera_id + '|' + arr[i].area_id;
  }

  new OtosStatisticsFrame(params, config);
};

var OtosStatisticsFrame = function (paramStr, config)
{
  var aspectRatio   = 0.9;
  var defaultPeriod = 'day';
  var defaultId     = 'otos';
  var minRefresh    = 30;
  var baseUrl       = !config.baseUrl ? 'http://www.otosservice.net/' : config.baseUrl;
  var parentId      = !config.parent_id ? defaultId : config.parent_id;
  var container     = document.getElementById(parentId);
  var cType         = !config.chart ? '' : config.chart;
  var stat          = config.stat_type == undefined ? '' : config.stat_type;

  if (!container)
    throw ('Container element doesn\'t exist');

  var src = baseUrl + 'chart.php?';
  var el  = document.createElement('iframe');

  // get the config
  var scale     = !config.scale ? aspectRatio : parseFloat(config.scale);
  var width     = !config.width ? container.clientWidth : config.width;
  var height    = !config.height ? scale * width : config.height;
  var period    = !config.period ? defaultPeriod : config.period;
  var styleStr  = '';

  // get the styles
  if (config.styles)
  {
    var arr = [];

    for (var key in config.styles)
      arr.push(key + ":" + config.styles[key]);

    styleStr = arr.join('|');
  }

  // generate the document url
  src += '&chart_width=' + parseInt(width/* - 30*/) + '&chart_height=' + parseInt(height)
       + '&period=' + period.toUpperCase();

  // set the styles
  if (styleStr !== '')
    src += '&styles=' + styleStr;

  // set the chart type
  if (cType !== '')
    src += '&chart_type=' + cType;

  // set the statistics type
  if (stat !== '')
    src += '&stat=' + stat;

  // day offset is set?
  if (config.day_offset)
    src += '&day_offset=' + parseInt(config.day_offset);

  // start time is set?
  if (config.date_from)
    src += '&date_from=' + config.date_from;

  // append the extra parameters
  src += paramStr;

  // create the element
  el.setAttribute('src', src);
  el.setAttribute('width', width);
  el.setAttribute('height', height);
  el.setAttribute('frameborder', 0);
  el.setAttribute('scrolling', 'no');

  container.appendChild(el);

  // update the content document. just updating the src-attribute of the iframe
  // isn't enough
  el.contentWindow.location = src;

  // set auto-refresh
  if (config.refresh)
  {
    var refresh = parseInt(config.refresh) < minRefresh ? minRefresh : parseInt(config.refresh);
    window.setInterval(function () { el.src = src; }, refresh * 1000);
  }
};