
var controller = (function($) {
	
	var statusKey = {
			OPEN 	: 'OPEN',
			SERVING : 'SERVING',
			CLOSED 	: 'CLOSED'
	};
	
	var attributes,
		globalTicketText, globalTicketTextColor, globalTicketTextFontFamily, globalTicketTextFontSize,
        globalTicketTextFontStyle, globalTicketTextFontWeight, globalFlashDuration, globalShowFrame, globalFrameRadius, globalFlashSpeed, globalOpenText, globalClosedText,
        globalShowCustomerName, globalCustomerNameFontSize, globalCustomerNameFontFamily, globalCustomerNameFontStyle,
        globalShowWsName, globalCounterText,
		entryTemplate = '<div class="ticketEntry">' +
							'<div id="border" style="background-color:transparent;float:left;position:absolute;width: 100%;height:100%;z-index:-1;"></div>' + 
							'<div id="ticketDimensions" style="height: 100%; width: 100%; margin-top: 40px;">' +
								'<div id="serving" style="overflow: hidden; text-align: center;">' +
									'<div class="text_element">{{ticketText}}</div>' +
									'<div id="ticketNumber" class="ticketNumberStyle">{{ticketNumber}}</div>' +
									'<div class="stationNameStyle">{{workstationName}}</div>' +
								'</div>' +
							'</div>' +
						'</div>',
		statusTemplate = '<div class="ticketEntry">' +
							'<div id="border" style="background-color:transparent;float:left;position:absolute;width: 100%;height:100%;z-index:-1;"></div>' + 
							'<div id="ticketDimensions" style="height: 100%; width: 100%; margin-top: 40px;">' +
								'<div id="status" style="overflow: visible; text-align: center;">' +
									'<div class="status_text_element">{{statusText}}</div>' +
								 '</div>' +
							'</div>' +
						'</div>';
		
	
		var wwClient = qmatic.webwidget.client,
		attributeKeys = {
			TICKET_TEXT                 : 'text.above.ticket',
            TICKET_TEXT_COLOR           : 'text.above.ticket.color',
            TICKET_TEXT_FONT            : 'text.above.ticket.font',
            COUNTER_TEXT                : 'text.for.counter',
			TICKET_TOP_MARGIN           : 'top.margin',
			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',
			TICKET_FLASH_DURATION       : 'flash.duration',
			TICKET_DISP_WS_NAME         : 'display.workstationname',
			OPEN_TEXT					: 'open.text',
			CLOSED_TEXT					: 'closed.text',
			OPEN_COLOR					: 'open.color',
			CLOSED_COLOR				: 'closed.color',
			OPEN_FONT					: 'open.font',
			CLOSED_FONT					: 'closed.font',
			SHOW_FRAME          : 'show.frame',
			FRAME_RADIUS        : 'frame.radius',
			FLASH_SPEED		      : 'flash.speed',
			USE_SP_NAME         : 'use.sp.name',
			SHOW_CUSTOMER_NAME          : 'show.customername',
			CUSTOMER_NAME_FONT      		: 'customername.font'
		},
		attributeDefaults = {},
        ticketCall;
        var useSpName = false;
		
	function onWorkstationClose(topic, publisherData, subscriberData) {		
		var resultHtml;
		
		resultHtml = statusTemplate.replace(/\{\{statusText\}\}/g, (globalClosedText || ''));
		
		ticketCall.addEntry({
			html: resultHtml,
			flashDuration: globalFlashDuration,
      flashSpeed: globalFlashSpeed,
			status : statusKey.CLOSED,
      isCustomerName: isCustomerName
		});
	}
	
	function onWorkstationOpen(topic, publisherData, subscriberData) {		
		var resultHtml;
		
		resultHtml = statusTemplate.replace(/\{\{statusText\}\}/g, (globalOpenText || ''));
		
		ticketCall.addEntry({
			html: resultHtml,
			flashDuration: globalFlashDuration,
      flashSpeed: globalFlashSpeed,
			status : statusKey.OPEN,
      isCustomerName: isCustomerName
		});
	}
	
	function onCustomerCalledEvent(topic, publisherData, subscriberData) {		
		var resultHtml;

        // TODO if publisherData.prm.walkDirect == true, then ignore.
		
		if (publisherData && publisherData.prm.ticket) {
			$('#ticketCall').empty();
			
			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, globalCounterText + ' ' + (publisherData.prm.servicePointLogicId || ''));
  		}
			resultHtml = resultHtml.replace(/\{\{ticketText\}\}/g, (globalTicketText || ''));
						
				
			ticketCall.addEntry({
				html: resultHtml,
				flashDuration: globalFlashDuration,
        flashSpeed: globalFlashSpeed,
				status : statusKey.SERVING,
        isCustomerName: isCustomerName
			});

		}
	}
	
	function onTicketClose(topic, publisherData, subscriberData) {
		// wait one second for other events to catch up, then set CLOSED or OPEN depending on state.
		setTimeout(updateWorkstationStatus, 1000);
	}

    function onNoCustomersWaiting(topic, publisherData, subscriberData) {
        resultHtml = statusTemplate.replace(/\{\{statusText\}\}/g, (globalOpenText || ''));

        ticketCall.addEntry({
            html: resultHtml,
            flashDuration: globalFlashDuration,
            flashSpeed: globalFlashSpeed,
            status : statusKey.OPEN,
            isCustomerName: isCustomerName
        });
    }

    function updateWorkstationStatus() {
        // Adapted to R5. Commented out for now due to the connector call popping up a login dialog...
        wwClient.callConnector('/rest/widgetconnector/branches/' + wwClient.getBranchId() + '/positionalDisplays/' + wwClient.getUnitId() + '/status',
            function(status) {
                var lStatusText = undefined;
                var lStatusKey = undefined;
                if(status.state == 'OPEN' && status.state != 'SERVING') {
                    lStatusText = globalOpenText;
                    lStatusKey = statusKey.OPEN;
                } else if(!status.open) {
                    lStatusText = globalClosedText;
                    lStatusKey = statusKey.CLOSED;
                }

                if(lStatusText) {

                    var resultHtml = statusTemplate.replace(/\{\{statusText}}/g, (lStatusText || ''));

                    ticketCall.addEntry({
                        html: resultHtml,
                        flashDuration: globalFlashDuration,
                        flashSpeed: globalFlashSpeed,
                        status : lStatusKey,
                        isCustomerName: isCustomerName
                    });
                }
            }
        );
    }
	
	attributeDefaults[attributeKeys.TICKET_TEXT] = 'Now serving';
    attributeDefaults[attributeKeys.TICKET_TEXT_COLOR] = '#000000';
    attributeDefaults[attributeKeys.TICKET_TEXT_FONT] = 'Helvetica;46px;normal;normal';
    attributeDefaults[attributeKeys.COUNTER_TEXT] = 'Counter';
	attributeDefaults[attributeKeys.TICKET_TOP_MARGIN] = '40';
	attributeDefaults[attributeKeys.TICKET_BACKGROUND_COLOR] = '#E5EDFF';
	attributeDefaults[attributeKeys.TICKET_BACKGROUND_TRANSPARENCY] = 100;
	attributeDefaults[attributeKeys.TICKET_NUMBER_COLOR] = '#000000';
	attributeDefaults[attributeKeys.TICKET_NUMBER_FONT] = 'Helvetica;46px;normal;normal';
	attributeDefaults[attributeKeys.TICKET_STATION_COLOR] = '#000000';
	attributeDefaults[attributeKeys.TICKET_STATION_FONT] = 'Helvetica;28px;normal;normal';
	attributeDefaults[attributeKeys.TICKET_FLASH_DURATION] = 2700;
	attributeDefaults[attributeKeys.TICKET_DISP_WS_NAME] = 'false';
	attributeDefaults[attributeKeys.OPEN_TEXT] = "Open";
	attributeDefaults[attributeKeys.CLOSED_TEXT] = "Closed";
	attributeDefaults[attributeKeys.OPEN_COLOR] = "#00FF00";
	attributeDefaults[attributeKeys.CLOSED_COLOR] =	"#FF0000";
	attributeDefaults[attributeKeys.OPEN_FONT] = "Helvetica;36px;normal;normal";
	attributeDefaults[attributeKeys.CLOSED_FONT] = "Helvetica;36px;normal;normal";
	attributeDefaults[attributeKeys.SHOW_FRAME] = true;
	attributeDefaults[attributeKeys.FRAME_RADIUS] = 15;
	attributeDefaults[attributeKeys.FLASH_SPEED] = 600;
	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),
				
				topMargin = attribParser.getString(attributeKeys.TICKET_TOP_MARGIN, attributeDefaults[attributeKeys.TICKET_TOP_MARGIN]) + 'px',
				
				ticketBackgroundColor = attribParser.getString(attributeKeys.TICKET_BACKGROUND_COLOR, attributeDefaults[attributeKeys.TICKET_BACKGROUND_COLOR]),
				ticketBackgroundTransparency = attribParser.getString(attributeKeys.TICKET_BACKGROUND_TRANSPARENCY, attributeDefaults[attributeKeys.TICKET_BACKGROUND_TRANSPARENCY]),
				ticketNumberColor = attribParser.getString(attributeKeys.TICKET_NUMBER_COLOR, attributeDefaults[attributeKeys.TICKET_NUMBER_COLOR]),
				ticketNumberFontSize = attribParser.getFontSize(attributeKeys.TICKET_NUMBER_FONT, defaultsParser.getFontSize(attributeKeys.TICKET_NUMBER_FONT)),
				ticketNumberFontFamily = attribParser.getFontFamily(attributeKeys.TICKET_NUMBER_FONT, defaultsParser.getFontFamily(attributeKeys.TICKET_NUMBER_FONT)),
				ticketNumberFontStyle = attribParser.getFontStyle(attributeKeys.TICKET_NUMBER_FONT, defaultsParser.getFontStyle(attributeKeys.TICKET_NUMBER_FONT)),
				ticketNumberFontWeight = attribParser.getFontWeight(attributeKeys.TICKET_NUMBER_FONT, defaultsParser.getFontWeight(attributeKeys.TICKET_NUMBER_FONT)),
				ticketStationColor = attribParser.getString(attributeKeys.TICKET_STATION_COLOR, attributeDefaults[attributeKeys.TICKET_STATION_COLOR]),
				ticketStationFontSize = attribParser.getFontSize(attributeKeys.TICKET_STATION_FONT, defaultsParser.getFontSize(attributeKeys.TICKET_STATION_FONT)),
				ticketStationFontFamily = attribParser.getFontFamily(attributeKeys.TICKET_STATION_FONT, defaultsParser.getFontFamily(attributeKeys.TICKET_STATION_FONT)),
				ticketStationFontStyle = attribParser.getFontStyle(attributeKeys.TICKET_STATION_FONT, defaultsParser.getFontStyle(attributeKeys.TICKET_STATION_FONT)),
				ticketStationFontWeight = attribParser.getFontWeight(attributeKeys.TICKET_STATION_FONT, defaultsParser.getFontWeight(attributeKeys.TICKET_STATION_FONT));
			
			globalShowWsName = attribParser.getBoolean(attributeKeys.TICKET_DISP_WS_NAME, defaultsParser.getBoolean(attributeKeys.TICKET_DISP_WS_NAME));
			
			globalFlashDuration = attribParser.getInteger(attributeKeys.TICKET_FLASH_DURATION, attributeDefaults[attributeKeys.TICKET_FLASH_DURATION]);
            globalTicketTextColor = attribParser.getString(attributeKeys.TICKET_TEXT_COLOR, attributeDefaults[attributeKeys.TICKET_TEXT_COLOR]);
            globalTicketTextFontFamily = attribParser.getFontFamily(attributeKeys.TICKET_TEXT_FONT, attributeDefaults[attributeKeys.TICKET_TEXT_FONT]);
            globalTicketTextFontSize = attribParser.getFontSize(attributeKeys.TICKET_TEXT_FONT, attributeDefaults[attributeKeys.TICKET_TEXT_FONT]);
            globalTicketTextFontStyle = attribParser.getFontStyle(attributeKeys.TICKET_TEXT_FONT, defaultsParser.getFontStyle(attributeKeys.TICKET_TEXT_FONT));
            globalTicketTextFontWeight = attribParser.getFontWeight(attributeKeys.TICKET_TEXT_FONT, defaultsParser.getFontWeight(attributeKeys.TICKET_TEXT_FONT));
			globalTicketText = attribParser.getString(attributeKeys.TICKET_TEXT, attributeDefaults[attributeKeys.TICKET_TEXT]);
            globalCounterText = attribParser.getString(attributeKeys.COUNTER_TEXT, attributeDefaults[attributeKeys.COUNTER_TEXT]);
			
			globalOpenText 		= attribParser.getString(attributeKeys.OPEN_TEXT, attributeDefaults[attributeKeys.OPEN_TEXT]);
			var openColor 		= attribParser.getString(attributeKeys.OPEN_COLOR, attributeDefaults[attributeKeys.OPEN_COLOR]);
			var openFontSize 	= attribParser.getFontSize(attributeKeys.OPEN_FONT, defaultsParser.getFontSize(attributeKeys.OPEN_FONT));
			var openFontFamily  = attribParser.getFontFamily(attributeKeys.OPEN_FONT, defaultsParser.getFontFamily(attributeKeys.OPEN_FONT));
			var openFontStyle 	= attribParser.getFontStyle(attributeKeys.OPEN_FONT, defaultsParser.getFontStyle(attributeKeys.OPEN_FONT));
			var openFontWeight	= attribParser.getFontWeight(attributeKeys.OPEN_FONT, defaultsParser.getFontWeight(attributeKeys.OPEN_FONT));
			
			globalClosedText = attribParser.getString(attributeKeys.CLOSED_TEXT, attributeDefaults[attributeKeys.CLOSED_TEXT]);
			var closedColor = attribParser.getString(attributeKeys.CLOSED_COLOR, attributeDefaults[attributeKeys.CLOSED_COLOR]);
			var closedFontSize 	= attribParser.getFontSize(attributeKeys.CLOSED_FONT, defaultsParser.getFontSize(attributeKeys.CLOSED_FONT));
			var closeFontFamily = attribParser.getFontFamily(attributeKeys.CLOSED_FONT, defaultsParser.getFontFamily(attributeKeys.CLOSED_FONT));
			var closeFontStyle 	= attribParser.getFontStyle(attributeKeys.CLOSED_FONT, defaultsParser.getFontStyle(attributeKeys.CLOSED_FONT));
			var closeFontWeight	= attribParser.getFontWeight(attributeKeys.CLOSED_FONT, defaultsParser.getFontWeight(attributeKeys.CLOSED_FONT));
			
			globalShowFrame = attribParser.getBoolean(attributeKeys.SHOW_FRAME, attributeDefaults[attributeKeys.SHOW_FRAME]);
			globalFrameRadius = attribParser.getInteger(attributeKeys.FRAME_RADIUS, attributeDefaults[attributeKeys.FRAME_RADIUS]);
			globalFlashSpeed = attribParser.getInteger(attributeKeys.FLASH_SPEED, attributeDefaults[attributeKeys.FLASH_SPEED]);

		  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;
			ticketCall = new qmatic.Positionalcallwidget({
				id						: 'ticketCall'
			});
			
			ticketCall.onBeforeShowEntry = function(entryElem, isCustomerName) {
				var numberElem,
					stationElem, statusElem;
				
				if (entryElem) {
					entryElem.find('.ticketEntry').css('background', ticketBackgroundColor);
					
					if(globalShowFrame){
						entryElem.find('.ticketEntry').css('box-shadow', '3px 2px 2px #C3C3C3');
					}
					entryElem.find('.ticketEntry').css('border-radius', globalFrameRadius + 'px');
					
					entryElem.find('#ticketDimensions').css('margin-top', topMargin);
                    entryElem.find('.text_element').css('color', globalTicketTextColor)
                        .css('font-size', globalTicketTextFontSize).css('font-family', globalTicketTextFontFamily)
                        .css('font-style', globalTicketTextFontStyle).css('font-weight', globalTicketTextFontWeight);
					
					if(entryElem.status == 'SERVING') {
						numberElem = entryElem.find('.ticketNumberStyle');
						
						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);
					} else if(entryElem.status == 'OPEN') {
						statusElem = entryElem.find('#status');
						statusElem.css('color', openColor).css('font-size', openFontSize)
							.css('font-family', openFontFamily).css('font-style', openFontStyle)
							.css('font-weight', openFontWeight);
					} else if(entryElem.status == 'CLOSED') {
						statusElem = entryElem.find('#status');
						statusElem.css('color', closedColor).css('font-size', closedFontSize)
							.css('font-family', closeFontFamily).css('font-style', closeFontStyle)
							.css('font-weight', closeFontWeight);
					}
					
					if(!globalShowWsName) {
						entryElem.find('.stationNameStyle').remove();
					}
				}
			};
			
			wwClient.subscribe(qmatic.webwidget.topic.VISIT_CALL, onCustomerCalledEvent);
			wwClient.subscribe(qmatic.webwidget.topic.SERVICE_POINT_CLOSE, onWorkstationClose);
			wwClient.subscribe(qmatic.webwidget.topic.SERVICE_POINT_OPEN, onWorkstationOpen);
			wwClient.subscribe(qmatic.webwidget.topic.VISIT_END, onTicketClose);
            wwClient.subscribe("com.qmatic.qp.topic.event.NO_CUSTOMERS_WAITING", onNoCustomersWaiting);
			
			// Calls the backend and tries to set a CLOSED or OPEN status if applicable. If currently serving or similar, it does nothing.
			updateWorkstationStatus();
		},
		
		onLoadError : function(message) {
			$('body').append('<p>Widget load error: ' + message + '</p>');
		}
	};
	
	
})(jQuery);