(function(){

  
  angular
  .module('izApp')
  .directive('heuerModules',heuerModulesDirective)

  /* 
	//@name filter groupBy
	//@desc groups array of objects by one of its fields. 
	//@dependecy underscore _
	//@example  ng-repeat="(groupKey,groupChunks) in Items | groupBy: 'Name'  , where Items = [{Name:"Adrian", Id:1},{Name:"Adrian", Id: 2}]
	//@author abarwicki
  */ 
 .filter('groupBy', function() {
    return _.memoize(function(items /*:Array*/, field /*:string*/ ) {
            return _.groupBy(items, field);
        }
    );
  })
  
  /* 
	@name filter trusted
	@desc sanitizes urls ( for example yt links for iframes) so they can be put into src attributes of iframe, img or scripts.
	@example {{ ctrl.youtube_link | trusted }}, where ctrl.youtube_link = "http://yt.com/watch/123"
	@author abarwicki
  */
  .filter('trusted', ['$sce', function ($sce) {
    return function(url /*:string*/ ) {
	    // youtube videos -> in case someone just copies link from the address bar, we transform the link to the 'embedded one'
	  	// example : https://www.youtube.com/watch?v=wtIKN0L3dCw  ->  https://www.youtube.com/embed/wtIKN0L3dCw
	  	if( url.indexOf("youtube")!== -1 ){
		  
		  var videoId = url.split('v=')[1];
		  
		  var ampersandPosition = videoId.indexOf('&');
		  if(ampersandPosition != -1) {
			videoId = video_id.substring(0, ampersandPosition);
		  }
		  
		  url = "https://www.youtube.com/embed/"+videoId;
		}  
        return $sce.trustAsResourceUrl(url);
    };
  }]);
  
  
  function heuerModulesDirective(){
	return {
	  restrict: 'E',
	  transclude: false,
	  replace:true,
	  scope: {},
	  controller: heuerModulesController,
	  template: '<div bind-html-compile="moduleMarkup"></div>'
	}
  }

  heuerModulesController.$inject=["$scope","$filter",'TemplateService','VeranstaltungenService','UtilService','$window'];
  function heuerModulesController($scope,$filter,TemplateService,VeranstaltungenService,UtilService,$window) {
	  var datefilter = $filter('date'), dateformatter = function(d) { return datefilter(d, 'dMyyyy'); };
	  var veranstaltung = $scope.$parent.veranstaltung;

	  $scope.firstContact = null;
	  if(veranstaltung.contacts && veranstaltung.contacts[0]){
		$scope.firstContact = veranstaltung.contacts[0];
	  }

	  			  var getCookie = function(cname) {
				var name = cname + "=";
				var ca = document.cookie.split(';');
				for(var i = 0; i < ca.length; i++) {
				  var c = ca[i];
				  while (c.charAt(0)==' ') {
					c = c.substring(1);
				  }
				  if (c.indexOf(name) == 0) {
					return c.substring(name.length,c.length);
				  }
				}
				return "";
			  }
			  $scope.determineFileTypeIcon = function(fileName,returnExtension) {
				var extension = '.txt';
				var iconClass = 'fa fa-file-text-o';
				if(!fileName){
				  if(returnExtension){
					return extension;
				  } else {
					return iconClass;
				  }
				}
				if(fileName.match(/\.gif$|\.jpg$|\jpeg$|\.png$/i)) {
				  	extension = '';
					iconClass =  'fa fa-file-image-o';
				}
				if(fileName.match(/\.ppt$/i)) {
				  	extension = '.ppt';
					iconClass =  'fa fa-file-powerpoint-o';
				}
				if(fileName.match(/\.xls$|xlsx$/i)) {
					extension='.xls';
					iconClass = 'fa fa-file-excel-o';
				}
				if(fileName.match(/\.pdf$/i)) {
				  	extension = '.pdf';
					iconClass = 'fa fa-file-pdf-o';
				}
				if(fileName.match(/\.zip$/i)) {
				  	extension = '.zip';
					iconClass = 'fa fa-file-archive-o';
				}
				if(returnExtension){
				  return extension;
				} else {
				  return iconClass;
				}
			  };
			  $scope.zugangscode = "";
			  $scope.zugangcodeValid = null;
			  $scope.showDocuments = false;
			  $scope.docVeranstaltungTitle = encodeURIComponent(veranstaltung.title);
			  $scope.docVeranstaltungOrt = encodeURIComponent(veranstaltung.location);
			  $scope.docVeranstaltungDate = encodeURIComponent($filter('date')(veranstaltung.startDate, 'd. MMM yyyy'));

			  var cookieName = "zugangscode_" + veranstaltung.code;
			  if(document.cookie.indexOf(cookieName) != -1){
				// Zugangscode wurde zuvor in Cookie encoded abgelegt, muss hier daher decoded werden
				var zugangscodeParsed = decodeURIComponent(getCookie(cookieName));
				if(zugangscodeParsed){
				  VeranstaltungenService.checkZugangscode(zugangscodeParsed,veranstaltung.code).then(function(isValid){
					$scope.showDocuments = isValid;
					if(isValid){
					  $scope.zugangscode = zugangscodeParsed;
					}
				  });
				}
			  }

			  // Zugangscode prüfen und Dokumente Anzeigen :o
			  $scope.checkZugangscodeAndShowDocuments = function(zugangscode,event){
				$scope.zugangsCodeForm.$submitted = true;
				if(!$scope.zugangsCodeForm.$valid) {
				  $scope.$broadcast('show-errors-check-validity');
				  return;
				}
				if(event == null || event.keyCode == 13){
				  VeranstaltungenService.checkZugangscode(zugangscode,veranstaltung.code).then(function(isValid){
					if(isValid){
					  var today = new Date();
					  var yyyy = today.getFullYear()+26;
					  document.cookie = "zugangscode_"+veranstaltung.code+"="+encodeURIComponent(zugangscode)+"; expires=Mon, 01 Jan "+yyyy+" 12:00:00 UTC; path=/";
					}
					$scope.showDocuments = isValid;
					$scope.zugangcodeValid = isValid;
				  });
				}
			  }

			  // Lädt das Dokument in die interne Anzeige - ('"\(;..;)/"') - Hurray
			  $scope.downloadDokument = function(zugangscode,dokumentId,anzeigename,extension){
				//$window.open('/api/heuer/cdn/veranstaltung/'+veranstaltung.code+'/dokument/'+dokumentId, '_blank');
				$window.open('/api/heuer/cdn/veranstaltung/'+veranstaltung.code+'/dokument/'+dokumentId+'/'+anzeigename+extension, '_blank');
				/*
				var form = document.createElement('form');
				form.method = 'post';
				form.action = '/api/heuer/cdn/veranstaltung/'+veranstaltung.code+'/dokument/'+dokumentId+'/'+anzeigename+extension;
				form.target = '_blank';
				form.id = 'downloadForm';
				form.enctype = 'application/x-www-form-urlencoded';

				var input = document.createElement('input'); //input element, text
				input.type = 'hidden';
				input.name = 'zugangscode';
				input.value=zugangscode;
				form.appendChild(input);
				document.body.appendChild(form);
				$("#downloadForm").submit();
				$("#downloadForm").remove();
				*/

				/* Geht im IE nicht ;( Der kann einfach kein Javascript
				VeranstaltungenService.downloadDokument(zugangscode, veranstaltung.code, dokumentId).then( function(response){
				  var file = new Blob([response], {type: 'application/pdf'});
				  var fileURL = URL.createObjectURL(file);
				  $window.open(fileURL);

				  // temp element a for president, download the created blob (Every user want to download it, when the link named "Herunterladen")
				  var link = document.createElement('a');
				  link.href=fileURL;
				  link.download=anzeigename+'.pdf';
				  link.click();
				  $window.URL.revokeObjectURL(fileURL);

				});
				*/

			  }

	  $scope.showMore = false;
	  $scope.freeModules = [];
	  $scope.moduleMarkup = "";
	  $scope.teilnehmenObj = null;
	  $scope.activateDate = activateDate;
	  $scope.einerHeute = einerHeute;
	  $scope.isActiveDate = isActiveDate;
	  $scope.agendaOfDay = agendaOfDay;
	  $scope.showMoreAndLess = showMoreAndLess;
	 

	  var moduleNameToFunction = {
		FREE: getFreeModuleDefaultMarkup,
		PARTNER: getPartnerDefaultMarkup,
		AGENDA: getAgendaDefaultMarkup,
		NEWS: getNewsDefaultMarkup,
		DOWNLOADS: getDokumentDefaultMarkup
	  };

	  function einerHeute(activeDate, agendas) {
		// Kommt einer der übergebenen Agendapunkte Heute vor?
		// Wir verwendet, um zu entscheiden, ob der Ort des 
		// Agendapunktes als Überschrift angezeigt wird.
		for(key in agendas) {
		  if(agendas[key].vortragstag == activeDate) {
			return true;
		  }
		}
		return false;
	  }

	  function isActiveDate(vortragstag) {
		// Vergleicht den Tag (ohne Uhrzeit) des Agendapuntes mit dem
		// Tag (ohne Uhrzeit) des ausgewählten Tabs
		return $filter('date')($scope.activeDate, 'dmY') == $filter('date')(vortragstag, 'dmY');
	  }

	  function agendaOfDay() {
		var day = dateformatter($scope.activeDate);
		return $scope.agendagruppiert[day];
	  }

	  function activateDate(activatedDate, elementClassToShow){
		$scope.activeDate = activatedDate;
		if($scope.showMore){
		  var elements = document.getElementsByClassName(elementClassToShow);
		  var classToAddIfHidden = elementClassToShow;
		  angular.forEach(elements, function(e,i){
			e.setAttribute("class","hide " + classToAddIfHidden);
		  });
		}
		$scope.showMore = false;
		return true;
	  }

	  function showMoreAndLess(elementClassToShow){
		var elements = document.getElementsByClassName(elementClassToShow);
		var classToAddIfHidden = elementClassToShow;
		if($scope.showMore){
		  angular.forEach(elements, function(e,i){
			e.setAttribute("class","hide " + classToAddIfHidden);
		  });
		  $scope.showMore = false;
		} else {
		  angular.forEach(elements, function(e,i){
			e.setAttribute("class", elementClassToShow);
		  });
		  $scope.showMore = true;
		}
	  }

	  var isFreeModuleDefaultMarkupRendered = false;
	  angular.forEach(veranstaltung.modules, function(module, index) {
		if(module.name == "FREE") {
		  $scope.freeModules.push(module);
		}
		if(veranstaltung.partners && module.name == "PARTNER") {
		  $scope.partners = veranstaltung.partners;

		  $scope.partners_grouped = _.groupBy(_.sortBy(veranstaltung.partners, function(partner) { return partner.partnerTyp.sort * 100 + partner.sort;}), function(partner) { return partner.partnerTyp.name;});
		  $scope.groupCount = Object.keys($scope.partners_grouped).length;
		  $scope.groupCountModulo= $scope.groupCount % 4;
		}
		if(module.name == "NEWS") {
		  $scope.newsData = module.news;
		}
		if(module.name == "DOWNLOADS"){
		  $scope.freeDocuments = $filter("filter")(module.dokumente,{codeNeeded:false});
		  $scope.protectedDocuments = $filter("filter")(module.dokumente, {codeNeeded:true});
		}
		if(module.name == "AGENDA") {
		  if(module.agenda.length > 0){
			
			$scope.agenda = module.agenda.map(function(item){
			  item.veranstaltungsort=item.veranstaltungsort?item.veranstaltungsort:"";
			  return item;
			});
			
			$scope.activeDate = module.agenda[0].vortragstag;
			$scope.vortragstage = null;
			var lastVortragstag = null;
			var vortragstage = [];
			angular.forEach(module.agenda, function(agendapunkt, index){
			  if( $filter('date')(lastVortragstag, 'dMyyyy') != $filter('date')(agendapunkt.vortragstag, 'dMyyyy')){
				vortragstage.push(agendapunkt.vortragstag);
				lastVortragstag = agendapunkt.vortragstag;
			  }
			});
			var dategrouper = function(v) { return dateformatter(v.vortragstag); };
			$scope.vortragstage = vortragstage;
			$scope.agendagruppiert = {};
			angular.forEach(
			  _.groupBy(module.agenda, function(vortrag) {
				return dategrouper(vortrag);
			  }),
			  function(agendasOfThatDay, day) {
				$scope.agendagruppiert[day] = _.groupBy(agendasOfThatDay, function(vortrag) { return vortrag.veranstaltungsort; });
			  }
			);
		  }
		}
		if(module.templateRendered && module.templateRendered.length > 0){
		  var dataBindingMarkup = "";
		  var dataBindingMarkupEnd = "";
		  dataBindingMarkup = '<free-module index="'+$scope.freeModules.indexOf($filter('filter')($scope.freeModules, {id:module.id})[0])+'">';
		  dataBindingMarkupEnd = '</free-module>';

		  $scope.moduleMarkup = $scope.moduleMarkup + dataBindingMarkup + module.templateRendered + dataBindingMarkupEnd;
		} else {
		  if (module.name == "FREE" && !isFreeModuleDefaultMarkupRendered) {
			$scope.moduleMarkup = $scope.moduleMarkup + freeModuleDefaultMarkup;
			isFreeModuleDefaultMarkupRendered = true;
		  }
		  if(typeof moduleNameToFunction[module.name] != "undefined"){
			$scope.moduleMarkup = $scope.moduleMarkup + moduleNameToFunction[module.name](module.id,TemplateService, $scope);
		  }
		}
	  });
  }  



  function getAgendaDefaultMarkup(moduleid,TemplateService,$scope) {
	$scope.defaultAgenda = 'Agenda wird geladen ....';
	TemplateService.getTemplateContentByName('heuer.veranstaltung.agenda').then( function(response){  $scope.defaultAgenda = response;});
	TemplateService.getTemplateContentByName('heuer.veranstaltung.agenda.print').then( function(response){  $scope.defaultAgendaPrint = response;});
	return '<section bind-html-compile="defaultAgenda"></section><section bind-html-compile="defaultAgendaPrint"></section>'; // Wird durch den Request der obigen Zeile dann mit dem eigentlichen Markup gefüllt
  }

  function getDokumentDefaultMarkup(moduleid,TemplateService,$scope) {
	$scope.defaultDokument = 'Downloads werden geladen ....';
	TemplateService.getTemplateContentByName('heuer.veranstaltung.dokumente').then( function(response){  $scope.defaultDokumente = response;});
	return '<div bind-html-compile="defaultDokumente" id="Downloads"></div>'; // Wird durch den Request der obigen Zeile dann mit dem eigentlichen Markup gefüllt
  }

  function getPartnerDefaultMarkup(moduleid,TemplateService,$scope) {
	$scope.defaultPartner = 'Partner werden geladen ....';
	TemplateService.getTemplateContentByName('heuer.veranstaltung.partner').then(function(response){  
		$scope.defaultPartner = response;
	});
	return '<div bind-html-compile="defaultPartner" id="Partner"></div>'; 
	// Wird durch den Request der obigen Zeile dann mit dem eigentlichen Markup gefüllt
  }
  
  var freeModuleDefaultMarkup = '<style type="text/css">div.free-module-default img { margin-right:10px; }</style>' + "\n";

  function getFreeModuleDefaultMarkup(moduleid,TemplateService){
	var freeModuleMarkup = '<div class="row content free-module" id="{{module.title}}" ng-if="module.contentboxes.length > 0" ng-repeat="module in freeModules | filter:{id:'+moduleid+'}"> \
  <h4 class="module-title">{{module.title}}</h4> \
  <div class="divider"></div> \
  <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12" ng-repeat="cb in module.contentboxes"> \
  <h4>{{cb.title}}</h4> \
  <div> \
  <div> \
  <span ng-if="cb.media">\
  <iz-image alt="{{cb.media.source}}" class="hidden-xs pull-left" lg="150xauto" md="150xauto" metadata="{{cb.media.strMetaData}}" size="150xauto" sm="100xauto" source="{{cb.media.escalatedUri}}" title="{{cb.media.source}}" xs="false"></iz-image> \
  </span>\
  <div class="markup-text" ng-bind-html="cb.text"></div> \
  </div> \
  <div class="clear"></div> \
  <div class="divider" ng-if="daten.length > 1"></div> \
  </div> \
  </div> \
  </div>' + "\n";
	return freeModuleMarkup;
  }

  function getNewsDefaultMarkup(moduleid, TemplateService,$scope){
	$scope.defaultNewsMarkup = 'News werden geladen ....';
	TemplateService.getTemplateContentByName('heuer.veranstaltung.default_news').then(function(response){
	  $scope.defaultNewsMarkup = response;
	});
	return '<div bind-html-compile="defaultNewsMarkup"></div>'; // Wird durch den Request der obigen Zeile dann mit dem eigentlichen Markup gefüllt

  }
}());