var options={};
var aEmployees=[],aAccruals=[],aEvents=[],aWorkdays=[],aPayrolls=[],aBalances=[],aColumns=[],aFormulas=[];
var aField={};
var condition={}, cformula='';
var Group={None: 0, Day: 1, Week: 2, Month:3, Year: 4};
var FieldName={TotalPresencia: 'TOTALATTENDANCE', HorasEstandar: 'STANDARDHOURS', Acumulador: 'ACCRUALS', Coste: 'PAYROLL', Balance: 'BALANCE', WorkedDays: 'WORKEDDAYS'};
var headerHeight=23;


function Report_Load_Vars() {
	options.title=opener.txtTitle.GetText();
	options.fromEmployee=opener.cmbFromEmployee.selectedKey;
	options.fromEmployeeValue=opener.cmbFromEmployee.value;
	options.toEmployee=opener.cmbToEmployee.selectedKey;
	options.toEmployeeValue=opener.cmbToEmployee.value;
	options.department=opener.cmbDepartment.selectedKey;
	options.departmentValue=opener.cmbDepartment.value;
	options.center=opener.cmbCenter.selectedKey;
	options.centerValue=opener.cmbCenter.value;
	
	options.group=Convert.Int(opener.cmbGroupDate.selectedKey);
	options.groupValue=opener.cmbGroupDate.value;
	options.viewChecks=opener.cmbViewPunches.selectedKey;
	options.viewChecksValue=opener.cmbViewPunches.value;
	options.fromDate=opener.cmbFromDate.value;
	options.toDate=opener.cmbToDate.value;
	options.employeePage=opener.chkPagePerEmployee.GetCheck();
	options.showValue=opener.chkShowValuation.GetCheck();
	options.showTotalWeek=opener.chkViewWeeklyTotal.GetCheck();
	options.showTotalMonth=opener.chkViewMonthlyTotal.GetCheck();
	options.showTotal=opener.chkViewEmployeeTotal.GetCheck();
	options.dutytime=opener.chkEmployeeDutyTime.GetCheck();
	options.showAllDays=opener.chkShowAllDays.GetCheck();
	
	aAccruals=opener.aAccruals;
	aPayrolls=opener.aPayrolls;
	aBalances=opener.aBalances;
	aColumns=opener.winCC.columns;
	aFormulas=opener.aFormulas;
	condition=opener.winCondition.values;
	//---------------------------------------------------------------------------------
	var divTest=document.createElement('div');
	divTest.style.width='85px'
	document.body.appendChild(divTest);
	for(var i in aColumns){
		divTest.innerHTML=aColumns[i][0];
		var currentHeight=Convert.Int(divTest.offsetHeight);
		if(headerHeight<currentHeight){ headerHeight=currentHeight; }
	}
	document.body.removeChild(divTest);
}
function Report_Load_Model() {
	{//Title---------------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('title','color:#592D00; font-size: 14pt; font-weight: bold; font-style: italic;');
		report.AddTable('title',{height: 30, border_top: true, border_left: true, border_right: true, border_color: '#EEE', className: 'title'});
		report.tables['title'].Add();
	}
	{//Head----------------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('header_label','color:#592D00; font-weight: bold;');
		report.AddStyle('header_value','color:#592D00; font-style: italic;');
		
		report.AddTable('head_single',{height: 16});
		report.tables['head_single'].Add({width: 100, border_left: true, border_color: '#EEE', className: 'header_label'});
		report.tables['head_single'].Add({border_right: true, border_color: '#EEE', className: 'header_value'});
		
		report.AddTable('head_double',{height: 16});
		report.tables['head_double'].Add({width: 100, border_left: true, border_color: '#EEE', className: 'header_label'});
		report.tables['head_double'].Add({width: 275, className: 'header_value'});
		report.tables['head_double'].Add({width: 100, className: 'header_label'});
		report.tables['head_double'].Add({border_right: true, border_color: '#EEE', className: 'header_value'});

		report.AddTable('head_issue',{height: 16});
		report.tables['head_issue'].Add({width: 100, border_left:true, border_color:'#EEE', className: 'header_label'});
		report.tables['head_issue'].Add({width: 400, className: 'header_value'});
		report.tables['head_issue'].Add({width: 140, className: 'header_label'});
		report.tables['head_issue'].Add({border_right:true, border_color: '#EEE', className: 'header_value'});
	}
	{//Column headers------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('headers','background: #E3E3E3 url(design.header.png) repeat-x 0 0; font-weight: bold;');
		report.AddTable('headers',{className: 'headers', height: headerHeight});
		if(options.group==Group.None){
			report.tables['headers'].Add({width: 80});
			report.tables['headers'].Add({width: 250});
		}
		else{
			if(options.group==Group.Day){
				report.tables['headers'].Add({width: 100});
				report.tables['headers'].Add({width: 230});
			}
			else{
				report.tables['headers'].Add({width: 330});
			}
		}
	}
	{//Employee------------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('employee','background: #DEDEDE url(design.report.png) repeat-x 0 -24px;');
		report.AddTable('employees',{className: 'employee', border_left:true, border_right:true, border_color: '#D9D9D9'});
		report.tables['employees'].Add();
	}
	{//Values--------------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('values','background:#F0F0F0;');
		//report.AddStyle('values.pair','background:#FFFFFF;');
		report.AddTable('values',{className: 'values',border_bottom: true, border_color: '#FFF'});
		if(options.group==Group.None){
			report.tables['values'].Add({width: 80});
			report.tables['values'].Add({width: 250});
		}
		else{
			if(options.group==Group.Day){
				report.tables['values'].Add({width: 100});
				report.tables['values'].Add({width: 230});
			}
			else{
				report.tables['values'].Add({width: 330});
			}
		}
	}
	{//Checks--------------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('checks','background:#FFF;color:#666;');
		report.AddStyle('check_pair_0','background:#FFF;color:#666;border-width: 1px 0 1px 1px;border-color: #CCC;border-style: solid;');
		report.AddStyle('check_pair_1','background:#FFF;color:#666;border-width: 1px 1px 1px 0px;border-color: #CCC;border-style: solid;');
		report.AddStyle('check_slash','background:#FFF;color:#666;border-width: 1px 0px 1px 0px;border-color: #CCC;border-style: solid;');
		
		report.AddTable('checks',{className: 'checks',padding:5, height: 20});
		report.tables['checks'].Add({width: 90,padding: 10});
		
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 4,padding:0});
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 3,padding:0});
		
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 4,padding:0});
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 3,padding:0});
		
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 4,padding:0});
		report.tables['checks'].Add({width: 77});
		report.tables['checks'].Add({width: 3,padding:0});
		
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 4,padding:0});
		report.tables['checks'].Add({width: 78});
		report.tables['checks'].Add({width: 3,padding:0});
	}	
	{//Total week----------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('week','background: #FFF5D4 url(design.report.png) repeat-x 0 -46px;');
		report.AddTable('week',{className: 'week',border_top:true,border_bottom:true,border_color: '#FFF'});
		report.tables['week'].Add({width: 150,className: 'blank'});
		report.tables['week'].Add({width: 180});
	}
	{//Total month----------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('month','background: #FFF5D4 url(design.report.png) repeat-x 0 -68px;');
		report.AddTable('month',{className: 'month',border_top:true,border_bottom:true,border_color: '#FFF'});
		report.tables['month'].Add({width: 150,className: 'blank'});
		report.tables['month'].Add({width: 180});
	}
	{//Total----------------------------------------------------------------------------------------------------------------------------------------------------------------
		report.AddStyle('total','background: #FFF5D4 url(design.report.png) repeat-x 0 -90px;');
		report.AddTable('total',{className: 'total',border_top:true,border_bottom:true,border_color: '#FFF'});
		report.tables['total'].Add({width: 150,className: 'blank'});
		report.tables['total'].Add({width: 180});
	}		
	for(var i=0,iLen=aColumns.length;i<iLen;i++){
		report.tables['headers'].Add({width: 95});
		report.tables['values'].Add({width: 95});
		report.tables['week'].Add({width: 95});
		report.tables['month'].Add({width: 95});
		report.tables['total'].Add({width: 95});
	}
	if(aColumns.length>4){ report.orientation=1; }
}
function Report_Load_Data(){
	AjaxManager.Create('basic');
	AjaxManager.Create('closure');
	AjaxManager.Create('data');
	
	var gotAccruals=false, gotPayrolls=false, gotBalances=false;
	
	{//Get formula fields
		for(var i=0,iLen=aColumns.length; i<iLen; i++){
			var column=aColumns[i];
			if(column[1]=='Formula'){
				column.formula=column[3];
				var ajaxFormula=new Ajax("SELECT * FROM LISTADOS_FOR_COL{c} WHERE IdFormula='"+column[2]+"' ORDER By Alias", true);
				ajaxFormula.Send();
				if(!ajaxFormula.json.error){
					for(var j=0,jLen=ajaxFormula.json.row.length;j<jLen;j++){
						var item=ajaxFormula.json.row[j];
						switch(item.Tipo){
							case 'TotalAttendance': case 'StandardHours':
								column.formula=column.formula.replace(new RegExp(item.Alias,'g'), item.Tipo.toUpperCase());
								break;
							default:
								column.formula=column.formula.replace(new RegExp(item.Alias,'g'), item.Tipo.toUpperCase()+item.Valor);
								break;
						}
					}
				}
			}
			else{ column.formula=column[3].toUpperCase(); }
		}
		data.formula=condition.formula;
		for(var i=0, ilen=condition.columns.length; i<ilen; i++){
			var col=condition.columns[i];
			switch(col[2]){
				case 'TotalAttendance': case 'StandardHours':
					data.formula=data.formula.replace(new RegExp(col[0],'g'), col[2].toUpperCase());
					break;
				case 'Formula':
					var formula=aFormulas[col[3]].Value;
					var ajax_condition=Ajax("SELECT * FROM LISTADOS_FOR_COL{c} WHERE IdFormula='"+col[3]+"' ORDER By Alias", true);
					if(!ajax_condition.json.error){
						for(var j=0, jlen=ajax_condition.json.row.length; j<jlen; j++){
							var db=ajax_condition.json.row[j];
							switch(db.Tipo){
								case 'TotalAttendance': case 'StandardHours':
									formula=formula.replace(new RegExp(db.Alias, 'g'), db.Tipo.toUpperCase());
									break;
								default:
									formula=formula.replace(new RegExp(db.Alias, 'g'), db.Tipo.toUpperCase()+db.Valor);
									break;
							}
						}
					}
					data.formula='('+data.formula.replace(new RegExp(col[0],'g'), formula)+')';
					break;
				default:
					data.formula=data.formula.replace(new RegExp(col[0],'g'), col[2].toUpperCase()+col[3]);
					break;
			}
		}
		
		if(isFieldUsed(FieldName.TotalPresencia)){ setField(FieldName.TotalPresencia); }
		if(isFieldUsed(FieldName.HorasEstandar)){ setField(FieldName.HorasEstandar); }
		if(isFieldUsed(FieldName.WorkedDays)){ setField(FieldName.WorkedDays); }
		
		for(var i in aAccruals){
			if(isFieldUsed(FieldName.Acumulador+i)){
				setField(FieldName.Acumulador, i); 
				gotAccruals=true;
			}
		}
		
		for(var i in aPayrolls){
			if(isFieldUsed(FieldName.Coste+i)){
				setField(FieldName.Coste, i); 
				gotPayrolls=true;
			}
		}
		
		for(var i in aBalances){
			var name=FieldName.Balance+i;
			if(isFieldUsed(name)){ 
				setField(FieldName.Balance, i);
				gotBalances=true;
				var accrual=i.substr(0, i.length-2);
				if(typeof(aField[FieldName.Acumulador+accrual])=="undefined"){
					setField(FieldName.Acumulador, accrual); 
					gotAccruals=true;
				}
			}
		}
	}
	{//Basic---------------------------------------------------------------------------------------------------------------------------------------------------------------------
		{//Events---------------------------------------------------------------------------------------------------------------------------------------------------------------------
			var ajaxEvents = new Ajax("SELECT Codigo,Descripcion FROM INCIDENCIAS{c} ORDER BY Codigo");
			AjaxManager.group['basic'].Add(ajaxEvents);
			ajaxEvents.oncomplete=function(){
				if(!this.json.error){
					for(var i=0,iLen=this.json.row.length;i<iLen;i++){
						var item=this.json.row[i];
						aEvents[item.Codigo]={ text: item.Codigo+' - '+item.Descripcion }
					}
				}
				else{ alert(this.text); }
			}
		}
		{//Workdays-------------------------------------------------------------------------------------------------------------------------------------------------------------------
			var ajaxWorkdays = new Ajax("SELECT Codigo,Descripcion FROM HORARIOS{c} ORDER BY Codigo");
			AjaxManager.group['basic'].Add(ajaxWorkdays);
			ajaxWorkdays.oncomplete=function(){
				if(!this.json.error){
					for(var i=0,iLen=this.json.row.length;i<iLen;i++){
						var item=this.json.row[i];
						aWorkdays[item.Codigo]={ text: item.Codigo+' - '+item.Descripcion }
					}
				}
				else{ alert(this.text); }
			}
		}
	}
	{//Where---------------------------------------------------------------------------------------------------------------------------------------------------------------------
		var whereItems=[];
		if (options.fromEmployee != 'All') {
			if(options.toEmployee=='None') { whereItems.push("e.Codigo = '"+options.fromEmployee+"'"); }
			else { whereItems.push("e.Codigo >= '"+options.fromEmployee+"' AND e.Codigo <= '"+options.toEmployee+"'"); }
		}
		if(options.department != 'All') { whereItems.push("e.IdUbicacion = '" + options.department + "'"); }
		if(options.center != 'All') { whereItems.push("e.IdCentro = '" + options.center + "'"); }
		var whereClausule = whereItems.join(' AND ');
		if(whereClausule!=''){ whereClausule=' AND '+whereClausule; }
	}
	{//Closure-------------------------------------------------------------------------------------------------------------------------------------------------------------------
		var sql="SELECT c.IdEmpleado, e.Nombre, e.Apellidos, c.Fecha, c.Semana, c.Mes, c.Anho, c.Incidencia, c.TipoDia, c.Total, c.HorasEstandar "+
		"FROM CIERRE{c} c INNER JOIN EMPLEADOS{c} e ON e.Codigo = c.IdEmpleado "+
		"WHERE c.Fecha >= '{0}' AND c.Fecha <= '{1}' {2} {3} "+
		"ORDER BY c.IdEmpleado, c.Fecha ASC";
		var ajaxClosure = new Ajax(Convert.Format(sql, options.fromDate, options.toDate, options.showAllDays?"":"AND c.TipoDia <> 'D'", whereClausule));
		AjaxManager.group['closure'].Add(ajaxClosure);
		ajaxClosure.oncomplete=function(){
			for(var i=0,iLen=this.json.row.length;i<iLen;i++){
				var item=this.json.row[i];
				var id=item.IdEmpleado;
				var date=item.Fecha;
				if(IsInEmployees(id)){
					if(typeof(aEmployees[id])=="undefined"){
						aEmployees[id]={code: item.IdEmpleado, name: item.Nombre+' '+item.Apellidos,text: item.IdEmpleado+' - '+item.Nombre+' '+item.Apellidos, dates: [], duttytime: [], field: {}, balance: []};
						aEmployees[id].field[FieldName.TotalPresencia]=0;
						aEmployees[id].field[FieldName.HorasEstandar]=0;
						aEmployees[id].field[FieldName.WorkedDays]=0;
					}
					
					aEmployees[id].dates[date]={
						Incidencia: item.Incidencia,
						TipoDia: item.TipoDia,
						Semana: item.Semana,
						Mes: item.Mes,
						Anho: item.Anho,
						field:{},
						checks:[]
					};
					
					for(var x in aField){
						aEmployees[id].dates[date].field[x]=0;
					}
					
					aEmployees[id].field[FieldName.TotalPresencia]+=Convert.Int(item.Total);
					aEmployees[id].field[FieldName.HorasEstandar]+=Convert.Int(item.HorasEstandar);
					aEmployees[id].dates[date].field[FieldName.TotalPresencia]=item.Total;
					aEmployees[id].dates[date].field[FieldName.HorasEstandar]=item.HorasEstandar;
				}
			}
		}
	}
	{//Data----------------------------------------------------------------------------------------------------------------------------------------------------------------------
		whereClausule=whereClausule.replace(new RegExp('e.Codigo','gi'),"c.IdEmpleado");
		whereClausule=whereClausule.replace(new RegExp('e.Codigo','gi'),"c.IdEmpleado");
		{//Dutytime--------------------------------------------------------------------------------------------------------------------------------------------------------------
			if(options.group==Group.Month && options.dutytime && isFieldUsed(FieldName.HorasEstandar)){
				var fromYear=options.fromDate.substr(0,4);
				var toYear=options.toDate.substr(0,4);
				var ajaxDutytime=new Ajax(Convert.Format("SELECT * FROM EMPLEADOS_HORAS_ESTANDAR{c} c WHERE c.Anho>='{0}' AND c.Mes>='{1}' {2}",fromYear,toYear,whereClausule));
				AjaxManager.group['data'].Add(ajaxDutytime);
				ajaxDutytime.oncomplete=function(){
					for(var i=0,iLen=this.json.row.length;i<iLen;i++){
						var item=this.json.row[i];
						aEmployees[item.IdEmpleado].duttytime[item.Anho+item.Mes]=item.Total;
					}
				}
			}
		}
		{//Punches
			if((options.group==Group.Day && options.viewChecks!='none') || isFieldUsed(FieldName.WorkedDays)){
				var ajaxChecks= new Ajax(Convert.Format("SELECT c.IdEmpleado,FechaValor,Hora,HoraOriginal,IdIncidencia,IdTerminal FROM FICHAJES{c} c INNER JOIN EMPLEADOS{c} e ON c.IdEmpleado=e.Codigo "+
				"WHERE c.FechaValor>='{0}' AND c.FechaValor<='{1}' {2} ORDER BY IdEmpleado, Fecha, Hora",options.fromDate,options.toDate,whereClausule));
				AjaxManager.group['data'].Add(ajaxChecks);
				ajaxChecks.oncomplete=function(){
					for(var i=0,iLen=this.json.row.length;i<iLen;i++){
						var db=this.json.row[i];
						var id=db.IdEmpleado;
						var date = db.FechaValor;
						if(typeof(aEmployees[id])!="undefined"){
							var punches = aEmployees[id].dates[date].checks;
							if(typeof(punches)!="undefined"){
								punches.push({Hora: (options.viewChecks=='RoundedChecks'?db.Hora:db.HoraOriginal), IdIncidencia: db.IdIncidencia});
								
								if(typeof(aEmployees[id].dates[date].field[FieldName.WorkedDays])!="undefined"){
									if(punches.length>=4){ aEmployees[id].dates[date].field[FieldName.WorkedDays]=1; }
									else if(punches.length>=2){ aEmployees[id].dates[date].field[FieldName.WorkedDays]=.5; }
								}
							}
						}
					}
				}
			}
		}
		{//Accruals
			if(gotAccruals){
				var sqlAccruals=[];
				for(var i in aField){ if(aField[i].type==FieldName.Acumulador){ sqlAccruals.push(aField[i].key); }}
				
				var ajaxAccruals = new Ajax(Convert.Format("SELECT IdEmpleado,IdAcumulador,Fecha,TotalTiempo FROM CIERRE_ACUMULADORES{c} c INNER JOIN EMPLEADOS{c} e ON c.IdEmpleado=e.Codigo WHERE c.Fecha >= '{0}' AND c.Fecha <= '{1}'{2} AND c.IdAcumulador IN ('{3}') ORDER BY IdEmpleado,Fecha", options.fromDate, options.toDate, whereClausule, sqlAccruals.join("','")));
				AjaxManager.group['data'].Add(ajaxAccruals);
				ajaxAccruals.oncomplete=function(){
					for(var i=0, iLen=this.json.row.length; i<iLen; i++){
						var item=this.json.row[i];
						var id=item.IdEmpleado;
						var date=item.Fecha;
						var fid=FieldName.Acumulador+item.IdAcumulador;
						if(typeof(aEmployees[id])!="undefined" && typeof(aEmployees[id].dates[date])!="undefined"){
							aEmployees[id].dates[date].field[fid]=item.TotalTiempo;
							if(typeof(aEmployees[id].field[fid])=="undefined"){ aEmployees[id].field[fid]=0 }
							aEmployees[id].field[fid]+=Convert.Int(item.TotalTiempo);
						}
					}
				}
			}
		}
		{//Payrolls
			if(gotPayrolls){
				var sqlPayrolls=[];
				for(var i in aField){ if(aField[i].type==FieldName.Coste){ sqlPayrolls.push(aField[i].key); }}
				
				var ajaxPayrolls = new Ajax(Convert.Format("SELECT IdEmpleado,IdCosteConcepto,Fecha,Tiempo FROM CIERRE_COSTES{c} c INNER JOIN EMPLEADOS{c} e ON c.IdEmpleado=e.Codigo WHERE c.Fecha >= '{0}' AND c.Fecha <= '{1}'{2} AND c.IdCosteConcepto IN ('{3}') ORDER BY IdEmpleado,Fecha",options.fromDate, options.toDate, whereClausule, sqlPayrolls.join("','")));
				AjaxManager.group['data'].Add(ajaxPayrolls);
				ajaxPayrolls.oncomplete=function(){
					for(var i=0, iLen=this.json.row.length; i<iLen; i++){
						var item=this.json.row[i];
						var id=item.IdEmpleado;
						var date=item.Fecha;
						var fid=FieldName.Coste+item.IdCosteConcepto;
						if(typeof(aEmployees[id])!="undefined" && typeof(aEmployees[id].dates[date])!="undefined"){
							aEmployees[id].dates[date].field[fid]=item.Tiempo;
							if(typeof(aEmployees[id].field[fid])=="undefined"){ aEmployees[id].field[fid]=0 }
							aEmployees[id].field[fid]+=Convert.Int(item.Tiempo);
						}
					}
				}
			}
		}
		{//Balances
			if(gotBalances){
				var ajax_balances=new Ajax("SELECT * FROM PERFILES_SALDOS{c} WHERE Publico=0 ORDER BY IdPerfil");
				AjaxManager.group['data'].Add(ajax_balances);
				ajax_balances.oncomplete=function(){
					for(var i=0, ilen=this.json.row.length; i<ilen; i++){
						var db=this.json.row[i];
						var id=db.IdPerfil;
						var key=db.IdAcumulador+';'+db.Periodo;
						if(typeof(aEmployees[id])!="undefined" && typeof(aField[FieldName.Balance+key])!="undefined"){
							if(db.Periodo=="2" && db.Anho!="None"){ key+=';'+db.Anho; }
							aEmployees[id].balance[key]=db.TiempoPermitido;
						}
					}
				}
			}
		}
	}
	AjaxManager.group['basic'].Start();
	AjaxManager.group['basic'].oncomplete=function(){ AjaxManager.group['closure'].Start(); }
	AjaxManager.group['closure'].oncomplete=function(){ AjaxManager.group['data'].Start(); }
}
function Report_Process_Data(){
	{//Header
		report.SetSection('head');
		report.Add('title',[options.title]);
		report.AddSpace(5,'head_double');
		report.Add('head_single',[LngStr('company',true),COMPANY.code+' - '+COMPANY.description]);
		report.Add('head_double',[LngStr('from',true),options.fromEmployeeValue,LngStr('to',true),options.toEmployeeValue]);
		report.Add('head_double',[COMPANY.department+':',options.departmentValue,COMPANY.center+':',options.centerValue]);
		report.Add('head_double',[LngStr('from_date',true),Convert.Date(options.fromDate),LngStr('to_date',true),Convert.Date(options.toDate)]);
		report.Add('head_double',[LngStr('group_by',true),options.groupValue,LngStr('view_checks',true),options.viewChecksValue,]);

		
		report.AddSpace(10,true);
		var colTitles=[];
		switch(options.group){
			case Group.None:
				colTitles.push(LngStr('code'));
				colTitles.push(LngStr('name'));
				break;
			case Group.Day:
				colTitles.push(LngStr('date'));
				colTitles.push(LngStr('workday')+'/'+LngStr('event'));
				break;
			case Group.Week:
				colTitles.push(LngStr('week'));
				break;
			case Group.Month:
				colTitles.push(LngStr('month'));
				break;
		}
		for(var i=0,iLen=aColumns.length;i<iLen;i++){ 
			colTitles.push(aColumns[i][0]);
		}
		report.Add('headers',colTitles);
		report.AddSpace(1,'');
	}
	{//Body
		report.SetSection('body');
		for(var i in aEmployees){
			data.employee(i);
			var employee=aEmployees[i];
			var lastWeek=0,lastMonth=0,lastYear=0;

			if(options.group!=Group.None){ data.add('employees', ['<div class="arrow"></div> '+employee.text]); }
			
			for(var j in employee.dates){
				var date = employee.dates[j];
				
				if(lastWeek==0){ lastWeek=date.Semana; }
				if(lastMonth==0){ lastMonth=date.Mes; }
				if(lastYear==0){ lastYear=date.Anho; }
					
				if(lastWeek!=0 && lastWeek!=date.Semana){ showLineWeek(lastWeek, lastYear); }
				if(lastMonth!=0 && lastMonth!=date.Mes){ showLineMonth(lastMonth); }
				
				for(var x in aField){
					if(lastWeek!=date.Semana){ 
						if(aField[x].type==FieldName.Balance){ if(aField[x].key.split()[1]=="0"){ aField[x].initial=null; } }
						else{ aField[x].week=0; }
					}
					if(lastMonth!=date.Mes){ 
						if(aField[x].type==FieldName.Balance){ if(aField[x].key.split()[1]=="1"){ aField[x].initial=null; } }
						else{ aField[x].month=0; }
					}
					if(lastYear!=date.Anho && aField[x].type==FieldName.Balance){ if(aField[x].key.split()[1]=="2"){ aField[x].initial=null; } }
					
					switch(aField[x].type){ 
						case FieldName.Balance:
							if(aField[x].initial==null){
								var key = aField[x].key;
								var keyyear = key+';'+lastYear;
								if(typeof(employee.balance[keyyear])!="undefined"){
									aField[x].initial = employee.balance[keyyear];
								}
								else if(typeof(employee.balance[key])!="undefined"){
									aField[x].initial = employee.balance[key];
								}
								else{
									aField[x].initial = "";
								}
								aField[x].day=aField[x].initial;
							}
							if(aField[x].day!=""){
								aField[x].day-=date.field[FieldName.Acumulador+aBalances[aField[x].key].Acumulador];	
							}
							
							aField[x].week=aField[x].day;
							aField[x].month=aField[x].day;
							aField[x].total=aField[x].day;
							break;
						default:
							aField[x].day=Convert.Float(date.field[x]);
							aField[x].week+=aField[x].day;
							aField[x].month+=aField[x].day;
							aField[x].total+=aField[x].day;
							break;
					}
				}
				
				if(options.group==Group.Day){
					let evenText = '';
					switch(date.TipoDia){
						case 'I':
							eventText = atext(aEvents, date.Incidencia);
							break;
						case 'D':
							eventText = LngStr('holiday');
							break;
						default:
							eventText = atext(aWorkdays, date.Incidencia);
							break;
					}
					
					showLine('values', [Convert.Date(j, true), eventText], showFields('day', false)); 
				}
				
				{//punches
					if(options.group==Group.Day && options.viewChecks!='none' && date.checks.length>0){
						
						var checks=[];
						var firstLine=true;
						var count=0;
						for(var y=0,yLen=date.checks.length;y<yLen;y++){
							checks.push(date.checks[y]);
							if(count==7){
								NewCheckLine(checks,firstLine);
								firstLine=false;
								checks=[];
							}
							count++;
						}
						NewCheckLine(checks,firstLine);
						data.add('space', [1, '']);
					}
				}
				
				data.checkrecord(date.field);
				
				lastWeek=date.Semana;
				lastMonth=date.Mes;
				lastYear=date.Anho;
			}
			{//totals
				showLineWeek(lastWeek, lastYear);
				showLineMonth(lastMonth);
				if(options.showTotal && options.group!=Group.None){ showLine('total', ['', LngStr('total',true)], showFields('total', true)); }
			}
			{//group none
				if(options.group==Group.None){ showLine('values',[employee.code, employee.name], showFields('total', false)); }
			}
			if(options.employeePage){ data.add('@break', []); };
			
			data.checktotal();
			resetFields();
		}
	}		
	data.render();
}

{//Functions
	var data={
		formula: '',
		data: {},
		id: null,
		employee: function(id){
			this.id=id;
			this.data[id]={show: condition.condition=='AtLeastOneRecord'?false:true, row: []};
		},
		add: function(table, values){
			this.data[this.id].row.push([table, values.slice(0)]);
		},
		checkrecord: function(fields){
			if(condition.condition!='Total'){
				var record=data.formula;
				for(var i in fields){
					record=record.replace(new RegExp(i, 'gi'), fields[i]);
				}
				try{ record=eval(record); } catch(e){ record=false; }
				
				if(record && condition.condition=='AtLeastOneRecord'){ this.data[this.id].show=true; }
				if(!record && condition.condition=='EveryRecord'){ this.data[this.id].show=false; }
			}
		},
		checktotal: function(){
			if(condition.condition=='Total'){
				var record=data.formula;
				for(var i in aField){
					record=record.replace(new RegExp(i, 'gi'), aField[i].total);
				}
				try{ record=eval(record); } catch(e){ record=false; }
				if(!record) { this.data[this.id].show=false; }
			}
		},
		render: function(){
			for(var i in this.data){
				if(this.data[i].show || this.formula==''){
					for(var j in this.data[i].row){
						var row=this.data[i].row[j];
						if(row[0]=='space'){ report.AddSpace(row[1][0], row[1][1]); }
						else{ report.Add(row[0], row[1]); }
					}
				}
			}
		}
	}
	
	function isFieldUsed(value){
		for(var i=0,iLen=aColumns.length;i<iLen;i++){
			if(aColumns[i].formula.indexOf(value)>=0){
				return true; 
			}
		}
		if(data.formula.indexOf(value)>=0){ return true; }
		return false;
	}
	function setField(type, key){
		var i=type+(typeof(key)=="undefined"?'':key);
		aField[i]={
			type: type, key: key,
			initial: null, day: 0, week: 0, month: 0, total: 0
		}
		return aField[i];
	}
	function resetFields(){
		for(var i in aField){
			setField(aField[i].type, aField[i].key);
		}
	}
	
	function showLine(style, array1, fields){
		data.add(style, array1.concat(fields));
	}
	function showLineWeek(week, year){
		if(options.group==Group.Week){ showLine('values', [FormatWeek(week, year)], showFields('week', false)); }
		else if(options.group==Group.Day && options.showTotalWeek){ showLine('week', ['', LngStr('total_week', true)], showFields('week', true)); }
	}
	function showLineMonth(month){
		if(options.group==Group.Month){ showLine('values', [LngStr('month_'+month)], showFields('month', false)); }
		else if(options.group==Group.Day && options.showTotalMonth){ showLine('month', ['', LngStr('total_month', true)], showFields('month', true)); }
	}
	
	function showFields(period, showzero){
		var values=[];
		for(var x in aColumns){
			var value=0;
			switch(aColumns[x][1]){
				case "Formula":
					value=aColumns[x].formula;
					for(var y in aField){
						value=value.replace(new RegExp(y, 'gi'), aField[y][period]);
					}
					value=eval(value);
					break;
				default:
					value=aField[aColumns[x].formula][period];
					break;
			}
			
			if(aColumns[x][2] != FieldName.WorkedDays){
				if(value==0 || value==""){
					value=showzero?"00:00":""; 
				}
				else{
					value=Convert.Minutes(value); 
				}
			}
			values.push(value);
		}
		return values;
	}
	
	function NewCheckLine(array,isNew){
		if(typeof(isNew)=="undefined"){ isNew=true; }
		if(array.length!=0){
			var rows=[];
			var styles=[]
			rows.push(iif(isNew,LngStr('checks',true),''));
			styles.push('');
			for(var i=0,iLen=array.length;i<iLen;i++){
				var check='';
				check+=Convert.Time(array[i].Hora);
				if(array[i].IdIncidencia!='0000'){ check+='['+array[i].IdIncidencia+']'; }
				rows.push(check);
				if(i%2==0){
					styles.push('check_pair_0');
					styles.push('check_slash');
					rows.push('-');
				}
				else{
					styles.push('check_pair_1');
					styles.push('');
					rows.push('');
				}
			}
			if(array.length%2!=0){
				styles.push('check_pair_1');
				styles.push('');
				
				rows.push('<span style="color:#C00;">'+LngStr('missing_check')+'</span>');
				rows.push('');
			}
			data.add('checks',rows,styles);
		}
	}
}