function $(id) {
	return document.getElementById(id);
}

/* As próximas funções exigem que as seguintes variáveis já estejam definidas (no header do html):
   firstDate, lastDate, lastHour
   yesterday
   selectedDate, selectedTab
   holidays[]
*/

var firstDay   = getDayFromDate(firstDate);
var firstMonth = getMonthFromDate(firstDate);
var firstYear  = getYearFromDate(firstDate);

var lastDay   = getDayFromDate(lastDate);
var lastMonth = getMonthFromDate(lastDate);
var lastYear  = getYearFromDate(lastDate);

var selectedDay   = getDayFromDate(selectedDate);
var selectedMonth = getMonthFromDate(selectedDate);
var selectedYear  = getYearFromDate(selectedDate);

var archive=(location.href.indexOf('datas')!=-1)?true:false;

/* funções iniciais e definições de variáveis */
if (isDayOff(selectedDate)) {
	var dayHours=[12,23];
} else {
	var dayHours=[10,17,23];
}

function makeAll() {
	/* agrupamento de funções para preencher uma página de visualização de arquivo */
	makeHeader();
	makeHome();
	makeLastCalendars(selectedDate);
}

function makeHeader() {
	/* cria a navegação superior do arquivo (data e horários) */
	content  = '';
	content += '<div id="box_header">';
	content += '<div id="box_header">';
	content += '<div id="h_data">'+getLongDate(selectedDay,selectedMonth,selectedYear)+'</div>';
	content += '<div id="h_tabs">';
	content += '<div id="tab1" class="t_unselected"><a href="javascript:loadTab(1);">'+dayHours[0]+'h</a></div>';
	lastTab=1;
	if (isDayOff(selectedDate)) {
		/* feriado ou fim-de-semana */
		if (selectedDate == lastDate) {
			/* é feriado, e o dia visitado é o último dia de publicação */
			if (lastHour == 23) {
				content += '<div id="tab2" class="t_unselected"><a href="javascript:loadTab(2);">'+dayHours[1]+'h</a></div>';
				lastTab=2;
			} else {
				lastTab=1;
			}
		} else {
			/* é feriado, mas não é o último dia de publicação */
			content += '<div id="tab2" class="t_unselected"><a href="javascript:loadTab(2);">'+dayHours[1]+'h</a></div>';
			lastTab=2;
		}
	} else {
		/* dia útil */
		if (selectedDate == lastDate) {
			/* dia útil, e o dia visitado é o último dia de publicação */
			if (lastHour == 17) {
				content += '<div id="tab2" class="t_unselected"><a href="javascript:loadTab(2);">'+dayHours[1]+'h</a></div>';
				lastTab=2;
			} else if (lastHour == 23) {
				content += '<div id="tab2" class="t_unselected"><a href="javascript:loadTab(2);">'+dayHours[1]+'h</a></div>';
				content += '<div id="tab3" class="t_unselected"><a href="javascript:loadTab(3);">'+dayHours[2]+'h</a></div>';
				lastTab=3;
			}
		} else {
			/* dia útil, mas não é o último dia de publicação */
			content += '<div id="tab2" class="t_unselected"><a href="javascript:loadTab(2);">'+dayHours[1]+'h</a></div>';
			content += '<div id="tab3" class="t_unselected"><a href="javascript:loadTab(3);">'+dayHours[2]+'h</a></div>';
			lastTab=3;
		}
	}
	content += '</div>';
	content += '<div id="h_line"></div>';
	content += '</div>';
	$('area_header').innerHTML = content;
	selectedHour = (selectedTab==0||selectedTab>lastTab)?lastTab:selectedTab;
	setSelected(selectedHour);
}

function makeHome() {
	/* cria um elemento iframe para receber a home, e preenche com o dia selecionado */
	pageName = selectedDate+'home_'+dayHours[selectedHour-1]+'.jhtm';
	$('area_iframe').innerHTML = '<iframe id="homeuol" name="homeuol" src="'+pageName+'" frameborder="0" scrolling="no" onLoad="adjustIframeHeight(this);"></iframe>';
}

function makeLastCalendars(cDate) {
	/* cria os calendários da lateral utilizando makeCalendar() */
	var previousCals = 0;
	var showPreviousCals = 11;
	var areaCalendar = $('area_calendar');

	var cal = new Calendar(getMonthFromDate(cDate), getYearFromDate(cDate));
	cal.addClass( parseInt( getDayFromDate(cDate), 10 ), "sel" );
	cal.setLinks( getObjectFromDate(lastDate) );
  areaCalendar.appendChild( cal.getTitle() );
	areaCalendar.appendChild( cal.get() );
	
	while ( haveCalendar(getPrevious(cDate,previousCals+1)) && previousCals <= showPreviousCals ) {
		previousCDate = getPrevious(cDate,previousCals+1);
    oneCal = new Calendar(getMonthFromDate(previousCDate), getYearFromDate(previousCDate));
    oneCal.setLinks( getObjectFromDate(lastDate) );
    areaCalendar.appendChild( oneCal.getTitle() );
		areaCalendar.appendChild( oneCal.get() );
		

		previousCals++;
	}
}

function makeYearCalendar() {
	/* cria o calendário anual utilizando makeCalendar() */
  var yearCalendars = $('year_calendars');
  var div;
	cnt = 0;
	for (currentYear=lastYear; currentYear>=firstYear; currentYear--) {
		if (currentYear == lastYear) {
			if (currentYear == firstYear)
				initialMonth = firstMonth;
			else
				initialMonth = 1;
			finalMonth = lastMonth;
		} else if (currentYear == firstYear) {
			initialMonth = firstMonth;
			if (currentYear == lastYear)
				finalMonth = lastMonth;
			else
				finalMonth = 12;
		} else {
			initialMonth = 1;
			finalMonth = 12;
		}
		for(m=finalMonth; m>=initialMonth; m--) {
			cnt++;
			div = document.createElement("div");
			cal = new Calendar(m, currentYear);
			cal.setLinks( getObjectFromDate(lastDate) );
			div.appendChild( cal.getTitle() );
			div.appendChild( cal.get() );
			yearCalendars.appendChild(div);
			if (cnt%4==0)
				yearCalendars.innerHTML += '<div class="break">&nbsp;</div>';
			else
				yearCalendars.innerHTML += '<div class="cspacer"></div>';
		}
	}
}

function loadTab(num) {
	pageName = selectedDate+'home_'+dayHours[num-1]+'.jhtm';
	$('homeuol').src = pageName;
	setSelected(num);
}

function setSelected(num) {
	$('tab1').className = 't_unselected';
	lst=1;
	if ($('tab2')) {
		$('tab2').className = 't_unselected';
		lst=2;
	}
	if ($('tab3')) {
		$('tab3').className = 't_unselected';
		lst=3;
	}
	if (num == 0) num = lst;
	$('tab'+num).className = 't_selected';
}

function fixHeight() {
	$('homeuol').style.height = homeuol.document.body.scrollHeight+15;
}

/* funções de apoio para manipulação de datas e strings */
var monthNames = ["[null]", "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];

var weekDaysNames = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"];

function getLongDate(day,month,year) {
	/* recebe o dia, mês e ano e retorna a data por extenso */
	return ( weekDaysNames[getWeekDayNumber(day,month,year)-1] + ", " + day + " de " + monthNames[month] + " de "+year );
}

function haveCalendar(cDate) {
	iDate = firstYear.toString()+pad(firstMonth).toString();
	fDate = lastYear.toString()+pad(lastMonth).toString();
	cDateNoDay = cDate.substring(0,6);
	if ( cDateNoDay >= iDate  &&  cDateNoDay <= fDate )
		return (true);
	return (false);
}

function isDayOff(somedate) {
	/* recebe uma data no formato yyyymmdd e retorna true para feriados ou finais de semana */
	if (inArray(somedate, holidays) || isWeekend(somedate)) return true;
	return false;
}

function inArray(needle,haystack) {
	for (hi in haystack)
		if (haystack[hi] == needle) return true;
	return false;
}

function isWeekend(somedate) {
	_y = getYearFromDate(somedate);
	_m = getMonthFromDate(somedate);
	_d = getDayFromDate(somedate);
	_w = getWeekDayNumber(_d,_m,_y);
	if (_w==1 || _w==7) return true;
	return false;
}

function pad(i) {
      return i=(i<10)?"0"+i:i;
}

/* 
  classe Calendar
*/
Calendar = function( month, year )
{
  this.CELL_WRAP = 7
  
  this.year = null;
  this.month = null;
  
  this.weekDaysHeader = [ "D", "S", "T", "Q", "Q", "S", "S" ];
  this.firstWeekDay = 0;
  this.firstDate = new Date();
  
  this.table = null;
  this.events = [];
  this.classes = [];
  
  this.init = function( month, year )
  {
    this.setYear( year );
    this.setMonth( month );
    this.resetFirstDate();
  }
  
  this.getMonth = function()
  {
    return this.month;
  }
  
  this.setMonth = function( month )
  {
    this.month = month;
  }
  
  this.getYear = function()
  {
    return this.year;
  }
  
  this.setYear = function( year )
  {
    this.year = year;
  }
  
  this.getFirstDate = function()
  {
    return new Date( this.firstDate.getTime() );
  }
  
  this.setFirstDate = function( firstDate )
  {
    this.firstDate = firstDate;
  }
  
  this.getFirstWeekDay = function()
  {
    return this.firstWeekDay;
  }
  
  this.setFirstWeekDay = function( firstWeekDay )
  {
    return this.firstWeekDay = firstWeekDay;
  }
  
  this.getWeekDaysHeader = function()
  {
    var weekDaysHeader = this.weekDaysHeader;
    for( var i = 0; i < this.getFirstWeekDay(); i++ )
    {
      weekDaysHeader.push( weekDaysHeader.shift() );
    }
    return weekDaysHeader;
  }
  
  this.setWeekDaysHeader = function( weekDaysHeader )
  {
    this.weekDaysHeader = weekDaysHeader;
  }
  
  this.getTable = function()
  {
    return this.table;
  }
  
  this.setTable = function( table )
  {
    return this.table = table;
  }

  this.getEvents = function()
  {
    return this.events
  }  
  
  this.setEvents = function( events )
  {
    return this.events = events;
  }
  
  this.addEvent = function( day, link )
  {
    return this.events[ parseInt( day, 10 ) ] = link;
  }
  
  this.getClasses = function()
  {
    return this.classes;
  }
  
  this.setClasses = function( classes )
  {
    return this.classes = classes;
  }
  
  this.addClass = function( day, className )
  {
    var classes = this.getClasses();
    
    if( !( day in classes ) )
    {
      classes[ day ] = [];
    }
    
    classes[ day ].push( className );
  }
  
  this.resetFirstDate = function()
  {
    this.setFirstDate( this.createDate( this.getYear(), this.getMonth(), 1 ) );
  }
  
  this.createDate = function( year, month, day )
  {
    var date = new Date();
    
    date.setFullYear( year );
    date.setMonth( month-1 );
    date.setDate( day );
    date.setHours( 0 );
    date.setMinutes( 0 );
    date.setSeconds( 0 );
    
    return date;
        
  }
  
  this.addDay = function( date, days )
  {
    days = days || 1;
    return date.setDate( date.getDate() + days );
  }
  
  this.get = function()
  {
    var table;
    
    if( this.getTable() === null )
    {
      this.resetTable();
    }

    table = this.getTable();
    //table.innerHTML = "";
    
    table.appendChild( this.getHead() );
    table.appendChild( this.getBody() );
    
    return table;
  }
  
  this.resetTable = function()
  {
    return this.setTable( document.createElement("table") );
  }
  
  this.getHead = function()
  {
    var thead = document.createElement("thead");
    var tr = document.createElement("tr");
    var th;
    var weekDays = this.getWeekDaysHeader();
    
    for( var i = 0; i < weekDays.length; i++ )
    {
      th = document.createElement("th");
      th.innerHTML = weekDays[i];
      tr.appendChild(th);
    }
    
    thead.appendChild(tr);
    return thead;
  }
  
  this.getDaysBefore = function()
  {
    var date = this.getFirstDate();
    var firstWeekDay = this.getFirstWeekDay();
    
    return (date.getDay()-firstWeekDay>=0?date.getDay()-firstWeekDay:7+date.getDay()-firstWeekDay);
  }
  
  this.getDaysAfter = function()
  {
    var firstWeekDay = this.getFirstWeekDay();
    var year = this.getMonth()==12?this.getYear()+1:this.getYear();
    var month = this.getMonth()==12?1:this.getMonth()+1;
    var date = this.createDate( year, month, 1 );
    
    return (date.getDay()-firstWeekDay>0?7-date.getDay()+firstWeekDay:(date.getDay()-firstWeekDay)*-1);
  }
  
  this.getBody = function()
  {
    var tbody = document.createElement( "tbody" );
    var tr = document.createElement( "tr" );
    var td;
    var firstDate = this.getFirstDate();
    var dayContainer;
    var days = 1;
    var events = this.getEvents();
    var classes = this.getClasses();
    
    for( var i = 0; i < this.getDaysBefore(); i++ )
    {
      td = document.createElement("td");
      td.innerHTML = "&nbsp;";
      tr.appendChild(td);

      if( days % this.CELL_WRAP === 0 )
      {
        tbody.appendChild( tr );
        tr = document.createElement( "tr" );
      }
      days++;
    }
    
    for( var date = new Date( this.getFirstDate().getTime() ); date.getMonth()===firstDate.getMonth(); this.addDay(date) )
    {
      td = document.createElement("td");
      
      console.log(date);
      
      if( date.getDate() in classes )
      {
        td.className = classes[ date.getDate() ].toString().replace( /,/g, " " );
      }
      
      if( date.getDate() in events )
      {
        dayContainer = document.createElement( "a" );
        dayContainer.href = events[ date.getDate() ];
      }
      else
      {
        dayContainer = document.createElement( "span" );
      }
      
      dayContainer.innerHTML = date.getDate();
      td.appendChild( dayContainer );
      tr.appendChild( td );
      
      if( days % this.CELL_WRAP === 0 )
      {
        tbody.appendChild( tr );
        tr = document.createElement( "tr" );
      }
      days++;      
    }
      
    for( i = 0; i < this.getDaysAfter(); i++ )
    {
      td = document.createElement("td");
      td.innerHTML = "&nbsp;";
      tr.appendChild(td);

      if( days % this.CELL_WRAP === 0 )
      {
        tbody.appendChild( tr );
        tr = document.createElement( "tr" );
      }
      days++;
    }
    
    //tbody.appendChild( tr );
    
    return tbody;    
    
  }
  
  this.init( month, year );
  
}

/* Extende a classe Calendar */
Calendar.prototype.getMonthName = function()
{
  var name;
  
  switch( this.getMonth() )
  {
    case 1 : name="Janeiro"; break;
    case 2 : name="Fevereiro"; break;
    case 3 : name="Março"; break;
    case 4 : name="Abril"; break;
    case 5 : name="Maio"; break;
    case 6 : name="Junho"; break;
    case 7 : name="Julho"; break;
    case 8 : name="Agosto"; break;
    case 9 : name="Setembro"; break;
    case 10 : name="Outubro"; break;
    case 11 : name="Novembro"; break;
    case 12 : name="Dezembro"; break;
  }
  
  return name;
}

Calendar.prototype.getTitle = function()
{
  var h3 = document.createElement("h3");
  h3.innerHTML = this.getMonthName()+"/"+this.getYear();
  
  return h3;
}

Calendar.prototype.setLinks = function( maxDate )
{
  var day = this.getFirstDate();
  var year = this.getYear();
  var month = this.getMonth().toString().length===1?"0"+this.getMonth().toString():this.getMonth().toString();
  var date;
  
  while( day.getTime() <= maxDate.getTime() && day.getMonth()+1 === this.getMonth() )
  {
    date = day.getDate().toString().length===1?"0"+day.getDate().toString():day.getDate().toString();
    this.addEvent( day.getDate(), ".?d="+year+month+date );
    this.addDay( day );
  }
}

/* fim da classe de Calendario */

function getInitialDay (month,year) {
	/* recebe  um mês e ano, e retorna o primeiro dia que tem arquivo da home */
	if (year < firstYear || year > lastYear)
		return (32);
	if (year > firstYear && year < lastYear)
		return (1);
	if (year == firstYear)
		if (month > firstMonth)
			return(1);
		else if (month == firstMonth)
			return(firstDay);
		else 
			return(32);
	if (year == lastYear)
		if (month > lastMonth)
			return(32);
		else 
			return(1);
}

function getLastDay (month,year) {
	/* recebe  um mês e ano, e retorna o último dia que tem arquivo da home */
	if (year < firstYear || year > lastYear)
		return (0);
	if (year > firstYear && year < lastYear)
		return (monthDays(month,year));
	if (year == lastYear)
		if (month > lastMonth)
			return(0);
		else if (month == lastMonth)
			return(lastDay);
		else 
			return(monthDays(month,year));
	if (year == firstYear)
		if (month < firstMonth)
			return(0);
		else 
			return(monthDays(month,year));

}

function getWeekDayNumber(day,month,year) {
	/* recebe o dia, mês e ano e retorna o número equivalente ao dia da semana */
	_a = Math.floor((14 - month)/12);
	_y = year - _a;
	_m = month + 12*_a - 2;
	_d = (day + _y + Math.floor(_y/4) - Math.floor(_y/100) + Math.floor(_y/400) + Math.floor((31*_m)/12)) % 7;
	return (_d+1);
}

function getYearFromDate(cDate) {
	/* retorna o ano a partir da data no formato yyyymmdd */
	return (parseInt(cDate.toString().substring(0,4),10));
}

function getMonthFromDate(cDate) {
	/* retorna o mês a partir da data no formato yyyymmdd */
	return (parseInt(cDate.toString().substring(4,6),10));
}

function getDayFromDate(cDate) {
	/* retorna o dia a partir da data no formato yyyymmdd */
	return (parseInt(cDate.toString().substring(6,8),10));
}

function getObjectFromDate(cDate) {
  /* retorna o objeto Date a partir da data no formato yyyymmdd */
  var date = new Date();
  date.setFullYear( getYearFromDate(cDate) );
  date.setMonth( getMonthFromDate(cDate)-1 );
  date.setDate( getDayFromDate(cDate) );
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);
  
  return date;
}

function monthDays(month,year) {
	/* recebe o mês e o ano, a retorna a quantidades de dias no mês */
	if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
		return 31;
	else if (month != 2)
		return 30;
	else if (((year % 4) == 0 && (year % 100)!=0) || (year % 400)==0)
		return 29;
	else
		return 28;
}

function getPrevious(cDate,n) {
	year = getYearFromDate(cDate);
	month = getMonthFromDate(cDate);
	day = getDayFromDate(cDate);
	m = month-n;
	if ( m<1 ) {
		m = m+12;
		year = year-1;
	} else if ( m>12 ) {
		m = m-12;
		year = year+1;
	}
	return(year.toString()+pad(m)+pad(day));
}
