/**
       * Local settings page
       * DDVTECH
       * for more information, see http://mistserver.org/index.php?title=Stand-alone_Configuration_Page
       */
       
       
      /**
       * Store a local copy of the data send by the server.
       * server is the URL, credentials hold the username, password and authstring and settings is the local copy.
       */
         var settings =
         {
            server: '',
            credentials:
            {
               username: "",
               password: "",
               authstring: ""
            },
            settings: {}
         };
         
         
      /**
       *  Table for long/short limit names
       */
         var ltypes =
         [
            ['kbps_max', 'Current bandwidth'],
            ['users', 'Concurrent users'],
            ['geo', 'Geolimited'],
            ['host', 'Hostlimited']
         ];
         
         /* Not currently supported but may return at a later time:
            ['kb_total', 'Total bandwidth'],
            ['duration', 'Duration'],
            ['str_kbps_min', 'Minimum bitrate'],
            ['str_kbps_max', 'Maximum bitrate']
         /*
         
         
      /**
       *  When the page loads, fix the menu and show the correct tab
       */
         $(document).ready(function()
         {
            $('#nav').children().each(function()
            {
               $(this).click(function()
               {
                  // remove currently selected' class
                  $('#nav').children().each(function()
                  {
                     $(this).attr('class', '');
                  });
                  
                  // select this one
                  $(this).attr('class', 'selected');
                  
                  // show correct tab
                  showTab($(this).text());
               });
               
            });
            
            // show login 'tab' and hide menu
            showTab('login');
            $('#nav').css('visibility', 'hidden');
         });
         
         
         // used on the overview and streams page. cleared when switching to another 'tab'.
         var sinterval = null;
         
         // and this one is used on the protocols page.
         var pinterval = null;
         
         // ..and the logs page.
         var logsinterval = null;
         
         // what kind of streams should be displayed? Format is [recorded, live];
         var streamsdisplay = [true, true];
         
         // used on the overview page to decide then to ask the controller for an update check
         var updatelastchecked;
         
      /**
       * Display a certain page. It contains a (giant) switch-statement, that builds a page depending on the tab requested
       * @param name the name of the tab
       * @param streamname only used when editing streams or protocols, the name of the edited (or new) stream/protocol. Also used with the 'embed' tab
       */
         function showTab(name, streamname)
         {
            // clear page and refresh interval
            $('#page').html('');
            clearInterval(sinterval);
            clearInterval(pinterval);
            clearInterval(logsinterval);
            
            switch(name)
            {
               case 'login':
               
                  var host = $('<input>').attr('type', 'text').attr('placeholder', 'HTTP://' + (location.host == '' ? 'localhost:4242' : location.host) + '/api');
                  var user = $('<input>').attr('type', 'text').attr('placeholder', 'USERNAME');
                  var pass = $('<input>').attr('type', 'password').attr('placeholder', 'PASSWORD');
                  var conn = $('<button>').click(function()	
                  {
                     // get login info
                     settings.credentials.username = user.val();
                     settings.credentials.password = pass.val();
                     settings.server = host.val() == '' ? host.attr('placeholder') : host.val().toLowerCase();
                     
                     // save username, URL in address
                     location.hash = user.val() + '@' + settings.server;
                     
                     // try to login
                     setHeaderState('logingin');
                     
                     loadSettings(function(errorstr)
                     {
                        if(errorstr == '')
                        {
                           setHeaderState('connected');
                           
                           $('#nav').css('visibility', 'visible');
                           
                           showTab('overview');
                           
                           // show overview as current tab - this only happens when logging out and then in
                           $('#nav').children().each(function()
                           {
                              if($(this).text() != 'overview')
                              {
                                 $(this).attr('class', '');
                              }else{
                                 $(this).attr('class', 'selected');
                              }
                           });
                           
                        }else{
                           setHeaderState('disconnected');
                           $('#header-host').text('');
                           $('#page').append($('<p>').text(errorstr));
                        }
                     });
                  }).text('login');
                  
                  $('#page').append(
                     $('<div>').attr('id', 'login').append(host).append(user).append(pass).append(conn)
                  );
                  
                  // if we 'enter' in host, user or pass we should try to login.
                  function hand(e)
                  {
                     if(e.keyCode == 13)
                     {
                        conn.trigger('click');  // conn = login button
                     }
                  }
                  
                  host.keypress(hand);
                  user.keypress(hand);
                  pass.keypress(hand);
                  
                  // retrieve address hash from URL
                  var adr = location.hash.replace('#', '').split('@');
                  
                  if(adr.length == 2)
                  {
                     // put it in the page
                     host.val(adr[1]);
                     user.val(adr[0]);
                  }
                  
                  break;
                  
               case 'overview':
                  
                  
                  loadSettings(function(){
                  
                     $uptodate = null;
                     if (settings.settings.LTS == 1)
                     {
                        if ((settings.settings.update == undefined) || (updatelastchecked == undefined) || ((new Date()).getTime() - updatelastchecked > 3600000))
                        {
                           settings.settings.checkupdate = true;
                           settings.settings.update = {};
                           updatelastchecked = (new Date()).getTime();
                           loadSettings(function()
                           { 
                              showTab('overview'); 
                           });
                        }
                        else
                        {
                           if (settings.settings.update.uptodate == 0)
                           {
                              $uptodate = $('<label>').text('version check').css('line-height','30px');
                              $uptodate.append(
                                 $('<span>').attr('class','red').text('Outdated version!').append(
                                    $('<button>').text('update').click(function(){
                                       settings.settings.autoupdate = true;
                                       loadSettings();
                                    })
                                 )
                              );
                           }
                        }
                     }
                     if (settings.settings.config.basepath == undefined) 
                     {
                        settings.settings.config.basepath = "";
                     }
                     
                     $('#page').append(
                        $('<div>').attr('id', 'editserver').append(
                           $('<label>').attr('for', 'config-host').text('host').append(
                              $('<input>').attr('type', 'text').attr('placeholder', 'HOST').attr('id', 'config-host').attr('value', settings.settings.config.host)
                           )
                        ).append(
                           $('<label>').attr('for', 'config-name').text('name').append(
                              $('<input>').attr('type', 'text').attr('placeholder', 'NAME').attr('id', 'config-name').attr('value', settings.settings.config.name)
                           )
                        ).append(
                           $('<label>').text('Version').append(
                              $('<span>').text(settings.settings.config.version)
                           ).append($uptodate)
                        ).append(
                           $('<label>').text('Base path').append(
                              $('<input>').attr('type','text').attr('placeholder','BASE PATH').attr('id','config-basepath').val(settings.settings.config.basepath)
                           )
                        ).append(
                           $('<label>').text('time').append(
                              $('<span>').text( formatDate(settings.settings.config.time) )
                           )
                        ).append(
                           $('<label>').text('Streams').append(
                              $('<span>').attr('id', 'cur_streams_online').text('retrieving data...')
                           )
                        ).append(
                           $('<label>').text('Viewers').append(
                              $('<span>').attr('id', 'cur_num_viewers').text('retrieving data...')
                           )
                        )
                     );
                     
                     function showStats()
                     {
                        getStatData(function(data)
                        {
                           $('#cur_streams_online').html('').text(data.streams[0] + ' of ' + data.streams[1] + ' online');
                           $('#cur_num_viewers').html('').text(data.viewers);
                        });
                     }
                     
                     // refresh the stream status + viewers
                     sinterval = setInterval(function()
                     {
                        showStats();
                     }, 10000);
                     
                     showStats();
                     
                     $('#editserver').append(
                        $('<button>').attr('class', 'floatright').click(function()
                        {
                           var host = $('#config-host').val();
                           var name = $('#config-name').val();
                           var path = $('#config-basepath').val();
                           
                           settings.settings.config.host = host;
                           settings.settings.config.name = name;
                           settings.settings.config.basepath = path;
                           
                           loadSettings(function()
                           {
                              showTab('overview');
                           });
                        }).text( 'save' )
                     );
                     
                     var forcesave = $('<div>').attr('id', 'forcesave');
                     
                     forcesave.append(
                        $('<p>').text('Click the button below to force an immediate settings save. This differs from a regular save to memory and file save on exit by saving directly to file while operating. This may slow server processes for a short period of time.')
                     ).append(
                        $('<button>').click(function()
                        {
                          if(confirmDelete('Are you sure you want to force a JSON save?') == true)
                          {
                             var host = $('#config-host').val();
                             var name = $('#config-name').val();
                             var path = $('#config-basepath').val();
                             
                             settings.settings.config.host = host;
                             settings.settings.config.name = name;
                             settings.settings.config.basepath = path;
                             
                             loadSettings(function()
                             {
                                forceJSONSave();
                                showTab('overview');
                             });
                          }
                        }).text( 'force save to JSON file' )
                     );
                     
                     $('#page').append(forcesave);
                  });
                  
                  break;
                  
                  
               case 'protocols':
                  
                  $table = $('<table>');
                  $table.html("<thead><th>Protocol</th><th>Status</th><th>Settings</th><th></th></thead>");
                  $tbody = $('<tbody>');
                  
                  var tr, i, protocol,
                     len = (settings.settings.config.protocols ? settings.settings.config.protocols.length : 0);
                  
                  $tbody.html('');
                  pids = [];
                  
                  for(i = 0; i < len; i++)
                  {
                     protocol = settings.settings.config.protocols[i];  // local copy
                     pids.push(i);
                     
                     tr = $('<tr>').attr('id', 'protocol-' + i);
                     
                     tr.append( $('<td>').text( protocol.connector ) );
                     
                     tr.append( $('<td>').html( formatStatus( protocol.online ) ) );
                     
                     s = "";
                     for (option in protocol) 
                     {
                        if ((option != 'connector') && (option != 'online')) 
                        {
                           s += option+': '+((protocol[option] == '') ||  (protocol[option] == 0) ? 'default' : protocol[option] )+', ';
                        }
                     }
                     s = s.slice(0,-2);
                       
                     tr.append( $('<td>').text( s ) ); 
                     
                     tr.append( $('<td>').attr('class', 'center').append( $('<button>').text('edit').click(function()
                     {
                        id = $(this).parent().parent().attr('id').replace('protocol-', '');
                        showTab('editprotocol', id);
                     }) ).append( $('<button>').click(function()
                     {
                        if(confirmDelete('Are you sure you want to delete this protocol?') == true)
                        {
                           var id = Number($(this).parent().parent().attr('id').replace('protocol-', ''));
                           var pid = pids.indexOf(id);
                           settings.settings.config.protocols.splice(pid, 1);
                           loadSettings(function()
                           {
                              showTab('protocols');
                           });
                        }
                     }).text('delete') ) );
                     
                     $tbody.append(tr);
                  }
                     
                  $table.append($tbody);
                  $('#page').append($table);
                      
                  $('#page').append(
                     $('<button>').attr('class', 'floatright').click(function()
                     {
                        showTab('editprotocol', 'new');
                     }).text('add new')
                  );
                  
                  function refreshProtocolStatus() 
                  {
                     getData(function(data)
                     {
                        $('tbody tr').each(function()
                        {
                           protocolstatus = null;
                           pid = $(this).attr('id').split('-')[1];
                           if (data.config.protocols[pid] == undefined) 
                           { 
                              protocolstatus = 'Protocol config missing.. reloading tab'; 
                              showTab('protocol');
                           }
                           else {
                              if (data.config.protocols[pid].online == undefined) 
                              {
                                 setTimeout(function()
                                 {
                                    refreshProtocolStatus();
                                 },1000);
                              }
                              protocolstatus = data.config.protocols[pid].online;
                           }
                           $(this).children(':nth-child(2)').html( formatStatus( protocolstatus ) );
                        });
                     });
                  }
                  
                  pinterval = setInterval(function()
                  {
                     refreshProtocolStatus();
                  },10000);
                  refreshProtocolStatus();
                  
                  break;
                  
               case 'editprotocol':
                  if (streamname != 'new') 
                  { 
                     currentdata = settings.settings.config.protocols[streamname]; 
                  }
                  
                  currentconnectors = [];
                  // build a list of the current connectors to see if the dependencies are already configured
                  for (var index in settings.settings.config.protocols) 
                  { 
                     currentconnectors.push(settings.settings.config.protocols[index].connector);
                  }
                  
                  function buildProtocolParameterFields(data,required)
                  {
                     for (fieldname in data)
                     {
                        switch(data[fieldname].type)
                        {
                           case 'str':
                              var inputType = 'text'
                              break;
                           case 'uint':
                              var inputType = 'number'
                              var func = 'uint'
                              break;
                           case 'int':
                              var inputType = 'number'
                              break;
                        }
                        $i = $('<input>').attr('type',inputType).attr('id','protocol-parameter-'+fieldname);
                        if (func == 'uint') 
                        {
                           $i.addClass('uint');
                        }
                        if (required) 
                        {
                           $i.addClass('required');
                        }
                        $protocolfields.append(
                           $('<label>').text(data[fieldname].name).attr('title',data[fieldname].help).append($i)
                        );
                     }
                  }
                  
                  function buildProtocolFields(selectedProtocol) 
                  {
                     data = settings.settings.capabilities.connectors[selectedProtocol];
                     
                     $t = $('<p>').text(data.desc);
                     if ((typeof data.deps != 'undefined') && (data.deps))
                     {
                        $t.append($('<p>').text('Dependencies:'));
                        $s = $('<ul>');
                        deps = data.deps.split(',');
                        for (var index in deps) 
                        {
                           t = deps[index];
                           if ($.inArray(deps[index],currentconnectors) < 0) 
                           {
                              $u = $('<span>').text(' (Not yet configured!)').addClass('red');
                           }else{
                              $u = $('<span>').text(' (Configured)').addClass('green');
                           }
                           $s.append($('<li>').text(t).append($u));
                        }
                        $t.append($s);
                     }						 
                     $('#protocoldesc').html( $t );
                     
                     $protocolfields = $('<div>');
                     if (typeof data.required != 'undefined') 
                     {
                        $protocolfields.append( $('<p>').text('Required parameters') );
                        buildProtocolParameterFields(data.required,true);
                     }
                     if (typeof data.optional != 'undefined') 
                     {
                        $protocolfields.append( $('<p>').text('Optional parameters') );
                        buildProtocolParameterFields(data.optional,false);
                     }
                     $('#protocolfields').html($protocolfields);
                     if (streamname != 'new') 
                     {
                        for (fieldname in currentdata) 
                        {
                           if ((fieldname != 'connector') && (fieldname != 'online')) 
                           { 
                              $('#protocol-parameter-'+fieldname).val(currentdata[fieldname]);
                           }
                        }
                     }
                  }
                     
                  loadSettings(function()
                  {
                     if (streamname == 'new') { t = 'add new protocol'; }
                     else { t = 'edit protocol'; }
                     
                     $('#page').append( $('<p>').text(t) );
                     
                     $selectprotocol = $('<select>').attr('id', 'edit-protocol').change(function()
                     {
                        buildProtocolFields($(this).children(':selected').val());						 
                     });
                     for(protocol in settings.settings.capabilities.connectors)
                     {
                        if ((streamname != 'new') && (currentdata.connector == protocol)) {
                           $selectprotocol.append(
                              $('<option>').attr('value', protocol).attr('selected','selected').text(protocol)
                           );
                        }else{
                           $selectprotocol.append(
                              $('<option>').attr('value', protocol).text(protocol)
                         );
                        }
                     }
                     
                     $div = $('<div>').attr('id', 'editprotocol');
                     $div.append( 
                        $('<label>').attr('for', 'protocol-edit-protocol').text('protocol').append(
                           $selectprotocol
                        )
                     );		
                     
                     $('#page').append( $div );
                     $('#editprotocol').append( $('<div>').attr('id','protocoldesc') );
                     $('#editprotocol').append( $('<div>').attr('id', 'protocolfields') );
                     $('#editprotocol').append(
                        $('<button>').text('cancel').addClass('floatright').click(function()
                        {
                           showTab('protocols');
                        })
                     );
                     $('#editprotocol').append(
                        $('<button>').text('save').addClass('floatright').click(function()
                        {
                           error = false;
                           //check if all required fields have contents
                           $('input.required').each(function()
                           { 
                              if ($(this).val() == '') 
                              {
                                 $(this).focus();
                                 $(this).parent().addClass('red');
                                 error = true;
                              }
                           });
                           
                           $('input[type="number"]').each(function()
                           { 
                              //make sure this is a number
                              if (isNaN($(this).val())) 
                              {
                                 $(this).focus();
                                 $(this).parent().addClass('red');
                                 error = true;
                              }
                              else
                              {
                                 //turn all numbers into integers
                                 $(this).val(Math.floor($(this).val()));
                              }
                           });
                           //check if all uints are actually uints
                           $('input.uint').each(function()
                           { 
                              if ($(this).val() < 0) 
                              {
                                 $(this).focus();
                                 $(this).parent().addClass('red');
                                 error = true;
                              }
                           });
                           if (error) { return; }
                           if(!settings.settings.config.protocols)
                           {
                              settings.settings.config.protocols = [];
                           }
                           
                           connectorval = $('#edit-protocol').val()
                           var newprotocol =
                           {
                              connector: connectorval
                           };
                           
                           $('input').each(function(){
                              newprotocol[$(this).attr('id').split('-')[2]] = $(this).val();;
                           });
                           newprotocol.online = -1;
                           if (streamname == 'new') {
                              settings.settings.config.protocols.push(newprotocol);
                           }else{
                              settings.settings.config.protocols[streamname] = newprotocol;
                           }
                           
                           loadSettings(function()
                           {
                              showTab('protocols');
                           });
                        })
                     );
                     
                     buildProtocolFields($('select#edit-protocol :selected').val());
                     
                  });
                  
                  break;
                  
               case 'streams':
                  
                  // the filter element containr
                  $div = $('<div>').attr('id', 'streams-filter');
                  
                  // filters the table. uses the streamsdisplay
                  function filterTable()
                  {
                     $('#streams-list-tbody').children().each(function(k, v)
                     {
                        var type = $($(v).children()[1]).text().toLowerCase();
                        
                        $(v).show();
                        
                        if(type == 'recorded' && streamsdisplay[0] == false)
                        {
                           $(v).hide();
                        }
                        
                        if(type == 'live' && streamsdisplay[1] == false)
                        {
                           $(v).hide();
                        }
                     });
                  }
                  
                  function filterOn(event, elem)
                  {
                     if(event.target.id == '')
                     {
                        return;  // label click goes bubbles on checkbox, so ignore it
                     }
                     
                     var what = $(elem).text();
                     
                     if(what == 'recorded')
                     {
                        streamsdisplay[0] = !streamsdisplay[0];
                        $('#stream-filter-recorded').attr('checked', streamsdisplay[0]);
                     }else{
                        streamsdisplay[1] = !streamsdisplay[1];
                        $('#stream-filter-live').attr('checked', streamsdisplay[1]);
                     }
                     
                     filterTable();
                  }
                  $div.append(
                     $('<label>').attr('for', 'stream-filter-recorded').text('recorded').append(
                        $('<input>').attr('type', 'checkbox').attr('id', 'stream-filter-recorded').attr('checked', streamsdisplay[0])
                           ).click(function(event)
                           {
                              filterOn(event, this);
                           })
                  );
                  $div.append(
                     $('<label>').attr('for', 'stream-filter-live').text('live').append(
                        $('<input>').attr('type', 'checkbox').attr('id', 'stream-filter-live').attr('checked', streamsdisplay[1])
                           ).click(function(event)
                           {
                              filterOn(event, this);
                           })
                  );
                  $('#page').append($div);
                  
                  // refresh every streams' data (status and viewer count)
                  function refreshStreams()
                  {
                     getStreamsData(function(streams)
                     {
                        $('tbody#streams-list-tbody tr').each(function()
                        {
                           streamstatus = null;
                           stream = $(this).attr('id').split('-')[1];
                           if (streams[stream] == undefined) 
                           { 
                              streamstatus = 'Stream config missing - reloading tab'; 
                              showTab('streams');
                           }
                           else
                           {
                              if (streams[stream][2])
                              {
                                 //there is an error
                                 streamstatus = formatStatus(streams[stream][0],streams[stream][2]);
                              }
                              else
                              {
                                 streamstatus = formatStatus(streams[stream][0]);
                              }
                           }
                           $(this).children(':nth-child(5)').html(formatStatus(streamstatus));
                           $(this).children(':nth-child(6)').html(streams[stream][1]);
                        });
                     });
                  };
                  
                  sinterval = setInterval(function()
                  {
                    refreshStreams();
                  }, 10000);
                  
                  refreshStreams();
                  
                  $table = $('<table>');
                  $table.html("<thead><th class=sort-type-int>Id</th><th class=sort-type-string>Type</th><th class=dontsort>Embed</th><th class='sort-type-string sortdesc'>Name</th><th class=sort-type-string>Status</th><th class=sort-type-int>Viewers</th><th class=dontsort>Edit</th></thead>");
                  $tbody = $('<tbody>');
                        
                  var stream, cstr, $tr;
                  
                  $tbody.html('').attr('id', 'streams-list-tbody');
                  
                  for(stream in settings.settings.streams)
                  {
                     
                     //backwards compatibility
                     //if sid does not yet exist, create it
                     if (settings.settings.streams[stream].sid == undefined) 
                     {
                        sid = 0;
                        for (strm in settings.settings.streams)
                        {
                           if (settings.settings.streams[strm].sid != undefined) 
                           { 
                              sid = Math.max(sid,settings.settings.streams[strm].sid); 
                           }
                        }
                        sid += 1;
                        settings.settings.streams[stream].sid = sid;
                     }
                     //if .source does not exist, create it
                     if ((settings.settings.streams[stream].source == undefined) && (settings.settings.streams[stream].channel != undefined))
                     {
                        settings.settings.streams[stream].source = settings.settings.streams[stream].channel.URL;
                     }
                     
                     var cstr = settings.settings.streams[stream];
                     
                     $tr = $('<tr>').attr('id', 'stream-' + stream);
                     
                     $tr.append( $('<td>').text( cstr.sid ) );
                     
                     $tr.append( $('<td>').text( TypeofResource( cstr.source ) ) );
                     
                     $tr.append( $('<td>').append( $('<button>').text('embed').click(function()
                     {
                        var sname = $(this).parent().parent().attr('id').replace('stream-', '');
                        showTab('embed', sname);
                     }) ) );   // end function, end click(), end append(), end append(). Huzzah jQuery.
                     
                     if ( cstr.name == undefined ) { cstr.name = ''; }
                     
                     $tr.append( $('<td>').text( cstr.name ) );
                     
                     if (cstr.error) 
                     {
                        $tr.append( $('<td>').html( formatStatus( cstr.online, cstr.error ) ) );
                     }
                     else
                     {
                        $tr.append( $('<td>').html( formatStatus( cstr.online ) ) );
                     }
                     
                     var cviewers = 0;
                     
                     if(settings.settings.statistics && settings.settings.statistics[stream])
                     {
                        if(settings.settings.statistics[stream] && settings.settings.statistics[stream].curr)
                        {
                           for(viewer in settings.settings.statistics[stream].curr)
                           {
                              cviewers++;
                           }
                        }
                     }else{
                        cviewers = 0;
                     }
                     
                     $tr.append( $('<td>').text( cviewers ) );
                     
                     $tr.append( $('<td>').append( $('<button>').text('edit').click(function()
                     {
                        var sname = $(this).parent().parent().attr('id').replace('stream-', '');
                        
                        showTab('editstream', sname);
                     }) ) );   // end function, end click, end append, end append.
                     
                     $tbody.append($tr);
                     
                     //quickly re-check if the streams are online now
                     if (cstr.online == undefined) 
                     {
                        setTimeout(function()
                        {
                          refreshStreams();
                        }, 1000);
                     }
                  }
                  
                  $table.append($tbody).addClass('sortable');
                  $table.stupidtable();
                  $('#page').append($table);
                  
                  // on page load, also filter with the (users' defined) stream filter
                  filterTable();
                  
                  $('#page').append(
                     $('<button>').attr('class', 'floatright').click(function()
                     {
                        showTab('editstream', 'new');
                     }).text('add new')
                  );
                  
                  break;
                  
               case 'editstream':
                  
                  var sdata, title;
                  
                  if(streamname == 'new')
                  {
                     sdata =
                     {
                        'name': '',
                        'source': '',
                        'limits': [],
                        'preset':
                        {
                           'cmd': ''
                        }
                     };
                     title = 'add new stream';
                  }else{
                     sdata = settings.settings.streams[streamname];
                     title = 'edit stream "' + sdata.name + '"';
                  }
                  sdata = $.extend({
                    'name': '',
                    'source': '',
                    'limits': [],
                    'preset':
                    {
                       'cmd': ''
                    }
                  },sdata);
                     
                  $('#page').append( $('<p>').text(title) );
                     
                  $('#page').append(
                     $('<div>').attr('id', 'editserver').append(
                        $('<label>').attr('for', 'stream-edit-name').text('name').append(
                           $('<input>').attr('type', 'text').attr('placeholder', 'NAME').attr('id', 'stream-edit-name').attr('value', sdata.name)
                        )
                     ).append(
                        $('<label>').attr('for', 'stream-edit-source').text('source').append(
                           $('<input>').attr('type', 'text').attr('placeholder', 'SOURCE').attr('id', 'stream-edit-source').attr('value', sdata.source).keyup(function()
                           {
                              var text = $(this).val();
                              
                              /*
                              if(text.charAt(0) == '/' || text.substr(0, 7) == 'push://')
                              {
                                 $('#stream-edit-preset').val('');
                                 $('#stream-edit-preset').hide();
                                 $('#stream-edit-preset-label').hide();
                              }else{
                                 $('#stream-edit-preset').show();
                                 $('#stream-edit-preset-label').show();
                              }
                              */
                              
                              if(text.charAt(0) == '/')
                              {
                                 $('#stream-edit-buffer').val('');
                                 $('#stream-edit-buffer').hide();
                                 $('#stream-edit-buffer-label').hide();
                              }else{
                                 $('#stream-edit-buffer').show();
                                 $('#stream-edit-buffer-label').show();
                              }
                           })
                        )
                     )
                     /*.append(
                        $('<label>').attr('id', 'stream-edit-preset-label').attr('for', 'stream-edit-preset').text('preset').append(
                           $('<input>').attr('type', 'text').attr('placeholder', 'PRESET').attr('id', 'stream-edit-preset').attr('value', sdata.preset.cmd)
                        )
                     ) */
                  );
                  
                  if (sdata.DVR == undefined) 
                  {
                    var DVR = '';
                  } else {
                    var DVR = sdata.DVR;
                  }
                  $('#editserver').append(
                    $('<label>').attr('id','stream-edit-buffer-label').attr('for','stream-edit-buffer').attr('title','Only applies to live streams').text('Buffer time [ms]').append(
                      $('<input>').attr('type','text').attr('placeholder','2 keyframes').attr('id','stream-edit-buffer').attr('value', DVR)
                    )
                  );
                  
                  // if the source is push or file, don't do a preset
                  var text = $('#stream-edit-source').val();
                  /*
                  if(text.charAt(0) == '/' || text.substr(0, 7) == 'push://')
                  {
                     $('#stream-edit-preset').hide();
                     $('#stream-edit-preset-label').hide();
                  }else{
                     $('#stream-edit-preset').show();
                     $('#stream-edit-preset-label').show();
                  } */
                  //if the source is not live, don't do DVR buffer time
                  if(text.charAt(0) == '/')
                  {
                     $('#stream-edit-buffer').val('');
                     $('#stream-edit-buffer').hide();
                     $('#stream-edit-buffer-label').hide();
                  }else{
                     $('#stream-edit-buffer').show();
                     $('#stream-edit-buffer-label').show();
                  }
                  
                  $('#editserver').append(
                     $('<button>').attr('class', 'floatright').click(function()
                     {
                        if(streamname == 'new')
                        {
                           showTab('streams');
                        }else{
                           if(confirmDelete('Are you sure you want to delete the stream "' + settings.settings.streams[streamname].name + '"?') == true)
                           {
                              delete settings.settings.streams[streamname];
                              loadSettings(function()
                              {
                                 showTab('streams');
                              });
                           }
                        }
                     }).text( streamname == 'new' ? 'cancel' : 'delete' )
                  );
                  
                  $('#editserver').append(
                     $('<button>').attr('class', 'floatright').click(function()
                     {
                        var n = $('#stream-edit-name');
                        var s = $('#stream-edit-source');
                        var p = $('#stream-edit-preset');
                        var b = $('#stream-edit-buffer');
                        
                        if(n.val() == ''){ n.focus(); return; }
                        if(s.val() == ''){ s.focus(); return; }
                        if((b.val() != '') && ((b.val() < 0) || (isNaN(b.val())))){ b.focus(); return; }
                        
                        var newname = n.val().replace(/([^a-zA-Z0-9_])/g, '').toLowerCase();
                        
                        sdata.name = newname;
                        sdata.source = s.val();
                        sdata.preset.cmd = p.val();
                        sdata.online = -1;
                        sdata.error = null;
                        if (b.val() != '') { sdata.DVR = b.val(); }
                        
                        if(streamname == 'new')
                        {
                           streamname = newname;
                           sdata.sid = 0;
                           for (strm in settings.settings.streams)
                           {
                              sdata.sid = Math.max(sdata.sid,settings.settings.streams[strm].sid); 
                           }
                           sdata.sid += 1;
                        }
                        else 
                        {
                           sdata.sid = settings.settings.streams[streamname].sid;
                        }
                        
                        if(!settings.settings.streams)
                        {
                           settings.settings.streams = {};
                        }
                        
                        delete settings.settings.streams[streamname];
                        
                        settings.settings.streams[newname] = sdata;
                        
                        loadSettings(function()
                        {
                           showTab('streams');
                        });
                           
                     }).text('save')
                  );
                  
                  break;
                  
               case 'embed':
                  
                  if(isThereAHTTPConnector())
                  {
                     var embedbase = 'http://' + parseURL(settings.server).host + ':' + getHTTPControllerPort() + '/';
                     
                     $('#page').append( $('<p>').attr('class', 'nocapitals').text('The info embed URL is "' + embedbase + 'info_' + streamname + '.js".') );
                     $('#page').append( $('<p>').attr('class', 'nocapitals').text('The embed embed URL is "' + embedbase + 'embed_' + streamname + '.js".') );
                     
                     $('#page').append( $('<button>').text('preview').click(function()
                     {
                        showTab('preview', streamname);
                     } ) );
                     
                  }else{
                     $('#page').append( $('<p>').attr('class', 'nocapitals').text('Could\'t find a HTTP connector. Please add a HTTP connector on the "protocol" page.') );
                  }
                  
                  break;
                  
               case 'preview':
                  
                  var embed = 'http://' + parseURL(settings.server).host + ':' + getHTTPControllerPort() + '/embed_' + streamname + '.js';
                  
                  $('#page').append( $('<div>').attr('id', 'previewcontainer') );
                  
                  // jQuery doesn't work -> use DOM magic
                  var script = document.createElement('script');
                  script.src = embed;
                  document.getElementById('previewcontainer').appendChild( script );
                  
                  break;
                  
               case 'limits':
                  if (settings.settings.LTS != 1) {
                    $('#page').html('Limits are not supported in your version. Buy the LTS! :)');
                    return;
                  } 
               
                  $table = $('<table>');
                  $table.html("<thead><th>Hard/soft</th><th>Type</th><th>Value</th><th>Applies to</th><th>Action</th></thead>");
                  $tbody = $('<tbody>');
                  
                  var i, tr, limit, stream, currentlims,
                      alllimits = settings.settings.config.limits;
                      
                  for(stream in settings.settings.streams)
                  {
                     currentlims = settings.settings.streams[stream].limits;
                     
                     for (index in currentlims) {
                       currentlims[index].appliesto = stream;
                       currentlims[index].appliesi = index;
                     }
                     
                     alllimits = alllimits.concat(currentlims);
                  }
                  
                  len = alllimits.length;
                  
                  // remove old items
                  $tbody.html('');
                  
                  //build current limits
                  for(i = 0; i < len; i++)
                  {
                     limit = alllimits[i];
                     $tbody.append(BuildLimitRow(limit));
                  }
                  for (stream in settings.settings.streams) {
                     for (limit in settings.settings.streams[stream].limits) {
                        delete settings.settings.streams[stream].limits[limit].appliesto;
                        delete settings.settings.streams[stream].limits[limit].appliesi
                     }
                  }
                   
                  $table.append($tbody);
                  $('#page').append($table); 
                  
                  //tooltip
                  $('.limits_type').live({
                     "mouseover": function(e){
                        removeTooltip();
                        showTooltip(e,undefined,$(this).children(':selected').data('desc'));
                     },
                     "mouseout": function(){
                        removeTooltip();
                     }
                  });
                  $('.limits_name').live({
                     "mouseover": function(e){
                        removeTooltip();
                        showTooltip(e,undefined,$(this).children(':selected').data('desc'));
                     },
                     "mouseout": function(){
                        removeTooltip();
                     }
                  });
                  
                  //change limit value box on type change
                  $('.limits_name').live("change", function(){
                     var value = $(this).parents('.limits_row').find(".limits_val").val();
                    $(this).parents('.limits_row').children('.limit_input_container').html('');
                    BuildLimitRowInput(
                      $(this).parents('.limits_row').children('.limit_input_container'),
                      {
                        'name': $(this).parents('.limits_row').find(".limits_name").val(),
                        'type': $(this).parents('.limits_row').find(".limits_type").val(),
                        'val': value
                      }
                    );
                  });
                  
                  //build buttons
                  $('#page').append(
                    $('<button>').text('Add limit').click(function(){
                      $tbody.append(BuildLimitRow({"name":"kbps_max", "val":0, "type":"soft"}));
                    })
                  ).append($('<br>')).append(
                    $('<button>').text('Save all').click(function(){
                      //clear current limits
                      settings.settings.config.limits = Array();
                      for (str in settings.settings.streams) {
                        settings.settings.streams[str].limits = Array();
                      }
                      
                      //add new limits
                      $tbody.children('tr').each(function(){
                        var newval = null;
                        switch ($(this).find(".limits_name").val()) {
                           case 'geo':
                              var entries = Array();
                              $(this).find('.limit_listentry').each(function(){
                                 var t = $(this).children(':selected').val();
                                 if (t != ''){
                                    entries.push(t);
                                 }
                              });
                              newval = $(this).find('.limit_listtype').children(':selected').val() + entries.join(' ');
                              break;
                           case 'host':
                           case 'time':
                              var t = $(this).find('.limit_listentry').val();
                              if ((t != undefined) && (t.toString().split(' ').length > 0)) {
                                 newval = $(this).find('.limit_listtype').children(':selected').val() + t;
                              }
                              break;
                           default:
                              newval = $(this).find(".limits_val").val();
                              break;
                        }
                        if (newval){
                           obj = {"type": $(this).find(".limits_type").val(), "name":$(this).find(".limits_name").val(), "val":newval};
                           if($(this).find('.new-limit-appliesto').val() == 'server') {
                             settings.settings.config.limits.push(obj);
                             //console.log('new server limit',obj);
                           }else{
                             settings.settings.streams[$(this).find('.new-limit-appliesto').val()].limits.push(obj);
                             //console.log('new stream limit',$(this).find('.new-limit-appliesto').val(),obj);
                           }
                        }
                      });
                      loadSettings(function(){
                        showTab('limits');
                      });
                    })
                  );
                  
                  break;
                  
               case 'logs':
                  $('#page').append(
                     $('<input>').attr('type','checkbox').addClass('logs_refresh')
                  ).append(
                     $('<span>').text(' Refresh logs every ')
                  ).append(
                     $('<select>').addClass('logs_refresh_every').append(
                        $('<option>').val(10000).text('10 seconds')
                     ).append(
                        $('<option>').val(30000).text('30 seconds')
                     ).append(
                        $('<option>').val(60000).text('minute')
                     ).append(
                        $('<option>').val(300000).text('5 minutes')
                     ).append(
                        $('<option>').val(600000).text('10 minutes')
                     ).append(
                        $('<option>').val(1800000).text('30 minutes')
                     )
                  ).append(
                     $('<button>').attr('class', 'floatright').click(function()
                     {
                        settings.settings.clearstatlogs = 1;
                        loadSettings(function()
                        {
                           showTab('logs');
                        });
                     }).text('Purge logs')
                  ).append(
                     buildLogsTable()
                  );
                  
                  var logsinterval; 
                  $('.logs_refresh').change(function(){
                     if ($(this).is(':checked')) {
                        var delay = $('.logs_refresh_every').val();
                        logsinterval = setInterval(function(){getLogsdata();},delay);
                        getLogsdata();
                     }
                     else {
                        clearInterval(logsinterval);
                     }
                  });
                  $('.logs_refresh_every').change(function(){
                     if ($('.logs_refresh').is(':checked')) {
                        var delay = $(this).val();
                        clearInterval(logsinterval);
                        logsinterval = setInterval(function(){getLogsdata();},delay);
                     }
                  });
                  
                  break;
                  
               case 'server stats':
                  loadSettings(function(){
                     serverstats = settings.settings.capabilities;
                     
                     if (serverstats.cpu !== undefined) 
                     {
                        $('#page').append(
                           $('<div>').attr('class','datacont').append(
                              $('<p>').text('CPU')
                           )
                        );
                        //be careful, only works if this is the first div to be constructed
                        for (property in serverstats.cpu[0]) 
                        {
                           $('#page div.datacont').append(
                              $('<label>').text(property).append(
                                 $('<span>').text(serverstats.cpu[0][property])
                              )
                           );
                        }
                     }
                     if (serverstats.mem !== undefined) 
                     {
                        $('#page').append(
                           $('<div>').attr('class','datacont').append(
                              $('<p>').text('Memory')
                           ).append(
                              $('<label>').text('Physical memory').append(
                                 $('<span>').text(serverstats.mem.used+'MiB/'+serverstats.mem.total+'MiB ('+serverstats.mem.free+'MiB available)')
                              )
                           ).append(
                              $('<label>').text('Swap memory').append(
                                 $('<span>').text((serverstats.mem.swaptotal - serverstats.mem.swapfree)+'MiB/'+serverstats.mem.swaptotal+'MiB ('+serverstats.mem.swapfree+'MiB available)')
                              )
                           )								
                        );
                     }
                     if (serverstats.load !== undefined) 
                     {
                        $('#page').append(
                           $('<div>').attr('class','datacont').append(
                              $('<p>').text('Load')
                           ).append(
                              $('<label>').text('Memory used').append(
                                 $('<span>').text(serverstats.load.memory+'%')
                              )
                           ).append(
                              $('<label>').text('Loading averages').append(
                                 $('<span>').text('1 min: '+serverstats.load.one+'%, 5 min: '+serverstats.load.five+'%, 15 min: '+serverstats.load.fifteen+'%')
                              )
                           )
                        );
                     }
                  });
                  
                  break;
               
               case 'disconnect':
                  showTab('login');
                  setHeaderState('disconnected');
                  $('#nav').css('visibility', 'hidden');
                  
                  settings =
                  {
                     server: '',
                     credentials:
                     {
                        username: "",
                        password: "",
                        authstring: ""
                     },
                     settings: {}
                  };
                  break;
            }  // end switch
            
            //placeholder for older browsers
            $('input[placeholder]').placeholder();
            
         }