$(function(){ 
"use strict";
   // for better performance - to avoid searching in DOM
   var content = $('#content');
   var input = $('#input');
   var status = $('#status');
   // my color assigned by the server
   var myColor = false;
   // my name sent to the server
   var myName = false;
   // if user is running mozilla then use it's built-in WebSocket
   window.WebSocket = window.WebSocket || window.MozWebSocket;
   // if browser doesn't support WebSocket, just show
   // some notification and exit
   if (!window.WebSocket) {
      content.html( $('<p>', { text:'Sorry, but your browser doesn\'t support WebSocket.'}) );
      input.hide();
      $('span').hide();
      return;
   }
   // open connection
   //var connection = new WebSocket('ws://127.0.0.1:8080');
   var url = 'ws://' + location.host + ':8080'; 
   var connection = null;
   //window.setInterval(makeConnection, 10000);
   makeConnection();
   window.setInterval(makeConnection, 3000);
   
   function makeConnection()
   {
      if (connection!==null)
		   return;
	
      connection = new WebSocket(url);
      
      connection.onopen = function () {
         // first we want users to enter their names
         input.prop('disabled', false).val('');
         status.text('Choose name:');
         
         content.html($('<p>', {
            text: 'Connection (re)opened.'
            }));
         
         if (location.search.length>0) {
            var variables = location.search.substr(1).split('&'); // array
            for (var i in variables)
            {
               var nameval = variables[i].split('=');
               if (nameval.length==2 && nameval[0]==='USR')
               {
                  input.prop('disabled', true);
                  myName = nameval[1]; 
                  break;
               }
            }
         }
         
         if (myName!==false)
         {
            connection.send(myName);
            input.val('');
         }
      };
      
      connection.onclose = function() {
         content.html($('<p>', {
            text: 'Connection closed.'
            }));
         connection = null;
      };
   
      connection.onerror = function (error) {
         // just in there were some problems with connection...
         content.html($('<p>', {
            text: 'Sorry, but there\'s some problem with your '
               + 'connection or the server is down.'
            }));
         //connection = null;
      };
  
      // most important part - incoming messages
      connection.onmessage = function (message) {
         // try to parse JSON message. Because we know that the server
         // always returns JSON this should work without any problem but
         // we should make sure that the message is not chunked or
         // otherwise damaged.
         try {
            var json = JSON.parse(message.data);
         } catch (e) {
            console.log('Invalid JSON: ', message.data);
            return;
         }
         // NOTE: if you're not sure about the JSON structure
         // check the server source code above
         // first response from the server with user's color
         if (json.type === 'color') { 
            myColor = json.data;
            status.text(myName + ': ').css('color', myColor);
            //input.removeAttr('disabled').focus();
            input.prop('disabled', false).focus();
            // from now user can start sending messages
         } else if (json.type === 'history') { // entire message history
            // insert every single message to the chat window
            for (var i=0; i < json.data.length; i++) {
               addMessage(json.data[i].author, json.data[i].text,
               json.data[i].color, new Date(json.data[i].time));
            }
         } else if (json.type === 'message') { // it's a single message
            // let the user write another message
            input.prop('disabled',false);
            if (json.data.constructor === Array) {
               addMessage(json.data[0].author, json.data[0].text,
                       json.data[0].color, new Date(json.data[0].time));
            }
            else {
               addMessage(json.data.author, json.data.text,
                       json.data.color, new Date(json.data.time));
            }
         } else if (json.type === 'verify') {
            content.prepend('<p>'+json.data+'</p>');
            input.prop('disabled', false).focus();
         } else {
            console.log('Hmm..., I\'ve never seen JSON like this:', json);
         }
      };
   }
  
   /**
    * Send message when user presses Enter key
   */
   input.keydown(function(e) {
      if (e.keyCode === 13) { // Enter
         var msg = $(this).val();
         if (!msg) {
           return;
         }
         // send the message as an ordinary text
         if (connection!==null) 
            connection.send(msg);
         
         $(this).val('');
         // disable the input field to make the user wait until server
         // sends back response
         input.prop('disabled', true);
         // we know that the first message sent from a user their name
         if (myName === false) {
            myName = msg;
         }
      }
   });
  
   /**
    * This method is optional. If the server wasn't able to
    * respond to the in 3 seconds then show some error message 
    * to notify the user that something is wrong.
   */
   window.setInterval(function() {
      if (connection!==null && connection.readyState > 1) {
         status.text('Error');
         input.prop('disabled', false).val(
             'Unable to communicate with the WebSocket server.');
         connection.close();
         connection = null;
      }
   }, 1000);
  
   /**
    * Add message to the chat window
   */
   function addMessage(author, message, color, dt) {
      content.prepend('<p><span style="color:' + color + '">'
        + author + '</span> @ ' + (dt.getHours() < 10 ? '0'
        + dt.getHours() : dt.getHours()) + ':'
        + (dt.getMinutes() < 10
          ? '0' + dt.getMinutes() : dt.getMinutes())
        + ': ' + message + '</p>');
   }
});  