var controller = (function ($) {

    var attributes,
        ticketHistory, counterText, globalShowFrame, globalFrameRadius,
        globalShowCustomerName, globalCustomerNameFontSize, globalCustomerNameFontFamily, globalCustomerNameFontStyle,
        entryTemplate = '<div class="ticketEntry"><div class="ticketNumberStyle">{{ticketNumber}}</div><div class="stationNameStyle">{{workstationName}}</div></div>',
        wwClient = qmatic.webwidget.client,
        attributeKeys = {
            BACKGROUND_COLOR: 'background.color',
            TICKET_HEIGHT: 'ticket.height.pixels',
            TICKET_BACKGROUND_COLOR: 'ticket.background.color',
		      	TICKET_BACKGROUND_TRANSPARENCY : 'ticket.background.transparency',
            TICKET_NUMBER_COLOR: 'ticket.number.color',
            TICKET_NUMBER_FONT: 'ticket.number.font',
            TICKET_STATION_COLOR: 'ticket.station.color',
            TICKET_STATION_FONT: 'ticket.station.font',
            COUNTER_TEXT: 'text.for.counter',
		       	SHOW_FRAME                  : 'show.frame',
	  		    FRAME_RADIUS                : 'frame.radius',
  			    USE_SP_NAME                 : 'use.sp.name',
	  		    TICKETS_MAX                 : 'tickets.max',
	  		    TICKETS_FADE                : 'tickets.fade',
      			SHOW_CUSTOMER_NAME          : 'show.customername',
      			CUSTOMER_NAME_FONT      		: 'customername.font'
        },
        attributeDefaults = {};


    function addTicket(publisherData) {

  			var isCustomerName = false;
  			
  			if(globalShowCustomerName == 0 || publisherData.prm.customers == '' || publisherData.prm.customers === undefined) {
  			  resultHtml = entryTemplate.replace(/\{\{ticketNumber\}\}/g, publisherData.prm.ticket) || '';
  			} else {
  			  
  			  var firstName = publisherData.prm.customers.split(' ').slice(0, -1).join(' ');
          var lastName = publisherData.prm.customers.split(' ').slice(-1).join(' ');
          var fullName = '';
          
    			switch(globalShowCustomerName) {
        		case 1:
        		  // John Doe
        		  fullName = publisherData.prm.customers;
    			    isCustomerName = true;
        		  break;
        		case 2:
        		  // J. Doe
        		  var firstNames = firstName.match(/\b(\w)/g);
    			    firstName = firstName.length > 0 ? firstNames.join('. ') + '. ' : '';
    			    fullName = firstName + lastName;
    			    isCustomerName = true;
        		  break;
        		case 3:
        		  // John D.
              firstName = firstName.length > 0 ? firstName + ' ' : '';
    			    lastName = lastName.length > 0 ? lastName.substring(0,1) + '.' : '';
    			    fullName = firstName + lastName;
    			    isCustomerName = true;
        		  break;
    			  default:
        		  fullName = entryTemplate.replace(/\{\{ticketNumber\}\}/g, publisherData.prm.ticket) || '';;
        		  isCustomerName = false;
        			break;
          }    			
  		    resultHtml = entryTemplate.replace(/\{\{ticketNumber\}\}/g, fullName) || '';
        }

  			if (useSpName) {			
  				resultHtml = resultHtml.replace(/\{\{workstationName\}\}/g, (publisherData.prm.servicePointName || ''));
  			} else {
          resultHtml = resultHtml.replace(/\{\{workstationName\}\}/g, counterText + ' ' + (publisherData.prm.servicePointLogicId || ''));
    		}
      ticketHistory.addEntry({
            html: resultHtml
        });
    }

    function onCustomerCalledEvent(topic, publisherData, subscriberData) {

        var resultHtml;

        if (publisherData && publisherData.prm.ticket) {
            // qmatic.webwidget.client.logInfo('CallHistory: Ticket call event received. Ticket: ' + publisherData.prm.ticket + ', Workstation: ' + publisherData.prm.servicePointLogicId);

            // Check if this might be a ticket recall. Do we have the same number/workstation already present in the DOM?
            // Check the five latest
            var items = $('.history-entry:lt(4)').find('.ticketEntry').find('.ticketNumberStyle:contains("' + publisherData.prm.ticket + '")').parent().find('.stationNameStyle:contains("' + publisherData.prm.servicePointLogicId + '")');
            if (items.length > 0) {
                var item = $(items[0]).parent().parent();
                var currentY = $(item).offset().top;

                // Get height of a ticket
                var height = $('.history-entry').css('height');
                height = parseInt(height.substring(0, height.length - 2));

                $(item).css('position', 'absolute');
                $(item).css('top', currentY + height);
                $(item).animate({
                    top: '0'
                }, 800, function () {
                    // After animation completes, remove the element and insert a brand new one
                    $(item).remove();
                    addTicket(publisherData);
                });
            } else {
                // New entry, just add the ticket
                addTicket(publisherData);
            }
        }
    }

    attributeDefaults[attributeKeys.TICKET_HEIGHT] = 120;
    attributeDefaults[attributeKeys.BACKGROUND_COLOR] = '#FFFFFF';
    attributeDefaults[attributeKeys.TICKET_BACKGROUND_COLOR] = '#E5EDFF';
	  attributeDefaults[attributeKeys.TICKET_BACKGROUND_TRANSPARENCY] = 100;
    attributeDefaults[attributeKeys.TICKET_NUMBER_COLOR] = '#000000';
    attributeDefaults[attributeKeys.TICKET_NUMBER_FONT] = 'Helvetica;38pt;normal;normal';
    attributeDefaults[attributeKeys.TICKET_STATION_COLOR] = '#000000';
    attributeDefaults[attributeKeys.TICKET_STATION_FONT] = 'Helvetica;20pt;normal;normal';
    attributeDefaults[attributeKeys.COUNTER_TEXT] = 'Counter';
  	attributeDefaults[attributeKeys.SHOW_FRAME] = true;
	  attributeDefaults[attributeKeys.FRAME_RADIUS] = 15;
  	attributeDefaults[attributeKeys.SHOW_CUSTOMER_NAME] = 0; // 0 = Do not show name
  	attributeDefaults[attributeKeys.CUSTOMER_NAME_FONT] = 'Helvetica;46px;normal;normal';

    // Public contents of controller
    return {
        /**
         * Called when widget client has finished loading. This is where you initialise your widget
         */
        onLoaded: function (configuration) {
            var attr = configuration.attributes;

            var attribParser = new qmatic.webwidget.AttributeParser(attr || {}),
                defaultsParser = new qmatic.webwidget.AttributeParser(attributeDefaults),
                ak = attributeKeys,
                ticketBackgroundColor = attribParser.getString(ak.TICKET_BACKGROUND_COLOR, attributeDefaults[ak.TICKET_BACKGROUND_COLOR]),
				        ticketBackgroundTransparency = attribParser.getString(attributeKeys.TICKET_BACKGROUND_TRANSPARENCY, attributeDefaults[attributeKeys.TICKET_BACKGROUND_TRANSPARENCY]),
                ticketNumberColor = attribParser.getString(ak.TICKET_NUMBER_COLOR, attributeDefaults[ak.TICKET_NUMBER_COLOR]),
                ticketNumberFontSize = attribParser.getFontSize(ak.TICKET_NUMBER_FONT, defaultsParser.getFontSize(ak.TICKET_NUMBER_FONT)),
                ticketNumberFontFamily = attribParser.getFontFamily(ak.TICKET_NUMBER_FONT, defaultsParser.getFontFamily(ak.TICKET_NUMBER_FONT)),
                ticketNumberFontStyle = attribParser.getFontStyle(ak.TICKET_NUMBER_FONT, defaultsParser.getFontStyle(ak.TICKET_NUMBER_FONT)),
                ticketNumberFontWeight = attribParser.getFontWeight(ak.TICKET_NUMBER_FONT, defaultsParser.getFontWeight(ak.TICKET_NUMBER_FONT)),
                ticketStationColor = attribParser.getString(ak.TICKET_STATION_COLOR, attributeDefaults[ak.TICKET_STATION_COLOR]),
                ticketStationFontSize = attribParser.getFontSize(ak.TICKET_STATION_FONT, defaultsParser.getFontSize(ak.TICKET_STATION_FONT)),
                ticketStationFontFamily = attribParser.getFontFamily(ak.TICKET_STATION_FONT, defaultsParser.getFontFamily(ak.TICKET_STATION_FONT)),
                ticketStationFontStyle = attribParser.getFontStyle(ak.TICKET_STATION_FONT, defaultsParser.getFontStyle(ak.TICKET_STATION_FONT)),
                ticketStationFontWeight = attribParser.getFontWeight(ak.TICKET_STATION_FONT, defaultsParser.getFontWeight(ak.TICKET_STATION_FONT)),
                ticketHeight = attribParser.getInteger(ak.TICKET_HEIGHT, attributeDefaults[ak.TICKET_HEIGHT]);

            counterText = attribParser.getString(ak.COUNTER_TEXT, attributeDefaults[ak.COUNTER_TEXT]);
      			globalShowFrame = attribParser.getBoolean(attributeKeys.SHOW_FRAME, attributeDefaults[attributeKeys.SHOW_FRAME]);
      			globalFrameRadius = attribParser.getInteger(attributeKeys.FRAME_RADIUS, attributeDefaults[attributeKeys.FRAME_RADIUS]);

      		  globalShowCustomerName = attribParser.getInteger(attributeKeys.SHOW_CUSTOMER_NAME, attributeDefaults[attributeKeys.SHOW_CUSTOMER_NAME]);
      			globalCustomerNameFontSize = attribParser.getFontSize(attributeKeys.CUSTOMER_NAME_FONT, defaultsParser.getFontSize(attributeKeys.CUSTOMER_NAME_FONT));
      			globalCustomerNameFontFamily = attribParser.getFontFamily(attributeKeys.CUSTOMER_NAME_FONT, defaultsParser.getFontFamily(attributeKeys.CUSTOMER_NAME_FONT));
      			globalCustomerNameFontStyle = attribParser.getFontStyle(attributeKeys.CUSTOMER_NAME_FONT, defaultsParser.getFontStyle(attributeKeys.CUSTOMER_NAME_FONT));
      			globalCustomerNameFontWeight = attribParser.getFontWeight(attributeKeys.CUSTOMER_NAME_FONT, defaultsParser.getFontWeight(attributeKeys.CUSTOMER_NAME_FONT));
      			
      			useSpName = attribParser.getBoolean(attributeKeys.USE_SP_NAME, false);
      
            var c = ticketBackgroundColor.replace('#', '');
            if(c.length == 6 & ticketBackgroundTransparency !== undefined) {
              if(ticketBackgroundTransparency > 100) { ticketBackgroundTransparency = 100; }
              if(ticketBackgroundTransparency < 0) { ticketBackgroundTransparency = 0; }
              ticketBackgroundColor = 'rgba(' + parseInt(c.substring(0,2),16) + ',' + parseInt(c.substring(2,4),16) + ',' + parseInt(c.substring(4,6),16) + ',' + (ticketBackgroundTransparency/100) + ')';
            }

            attributes = attr;
            ticketHistory = new qmatic.CallHistory({
                id: 'ticketHistory',
                entryHeight: ticketHeight + 'px',
                backgroundColor: attribParser.getString(ak.BACKGROUND_COLOR, attributeDefaults[ak.BACKGROUND_COLOR]),
                ticketsMax: attribParser.getString(ak.TICKETS_MAX, attributeDefaults[ak.TICKETS_MAX]),
                ticketsFade: attribParser.getString(ak.TICKETS_FADE, attributeDefaults[ak.TICKETS_FADE])
            });

            ticketHistory.onBeforeShowEntry = function (entryElem, isCustomerName) {
                var numberElem,
                    stationElem;

                if (entryElem) {
                    entryElem.css('height', ticketHeight - 3 /* subtract 3, otherwise the bottom part of ticket will be obscured, cutting out the shadow effect*/);
                    //entryElem.css('background-color', ticketBackgroundColor);
                    entryElem.css('background', ticketBackgroundColor);
                    numberElem = entryElem.find('.ticketNumberStyle');
          					if(globalShowFrame){
          						entryElem.css('box-shadow', '3px 2px 2px #C3C3C3');
          					}
          					entryElem.css('border-radius', globalFrameRadius + 'px');
          					if(isCustomerName) {
                      numberElem.css('color', ticketNumberColor).css('font-size', globalCustomerNameFontSize)
                          .css('font-family',  globalCustomerNameFontFamily).css('font-style',  globalCustomerNameFontStyle)
                          .css('font-weight',  globalCustomerNameFontWeight);
                    } else {
                      numberElem.css('color', ticketNumberColor).css('font-size', ticketNumberFontSize)
                          .css('font-family', ticketNumberFontFamily).css('font-style', ticketNumberFontStyle)
                          .css('font-weight', ticketNumberFontWeight);
                    }

                    stationElem = entryElem.find('.stationNameStyle');
                    stationElem.css('font-size', ticketStationFontSize).css('font-family', ticketStationFontFamily)
                        .css('color', ticketStationColor).css('font-style', ticketStationFontStyle)
                        .css('font-weight', ticketStationFontWeight);
                }
            };

            // R5 note: We can probably skip the entire if/else mess now since we only have VISIT_CALL to care about
            // We listen for customer ticket call event which is triggered whenever a workstation calls for the next
            // customer waiting in queue. Depending on which display type we're running on, we need to subscribe to different events.
            if (configuration.displayType == 'MEDIA' || configuration.displayType == 'TOUCH') {
                wwClient.subscribe(qmatic.webwidget.topic.VISIT_CALL, onCustomerCalledEvent);
            } else if (configuration.displayType == 'POSITIONAL') {
                wwClient.subscribe(qmatic.webwidget.topic.VISIT_CALL, onCustomerCalledEvent);
            } else {
                // MAIN?
                wwClient.subscribe(qmatic.webwidget.topic.VISIT_CALL, onCustomerCalledEvent);
            }
        },

        onLoadError: function (message) {
            $('body').append('<p>Widget load error: ' + message + '</p>');
        },

        onCleanUp: function () {
            // Perform cleanup of widget if necessary. Host allows 3 seconds worth of cleanup time before forcefully removing widget.
            if (window.console && window.console.log) {
                console.log('Call History cleanup');
            }
        }
    };


})(jQuery);
