<?php
// Copyright (c) 2001-2008, Björn Victor <Bjorn@Victor.se>

require_once($_SERVER['DOCUMENT_ROOT']."/../php/init.php");
require_once(
"htlang.php");    // check preferred language
$lang htlang();

$page_title = ($lang == 'sv' 'Allmänna helgdagar' 'Swedish Public Holidays');

if (
$lang == 'sv') {        // set up date printing correctly
  
if (function_exists("version_compare") and version_compare("4.3.0",phpversion()) != 1) {
    
// at least 4.3.0
    
setlocale(LC_TIME,"sv","sv_SE");
  } else {
    
// older
    
setlocale(LC_TIME,"sv_SE");
  }
}

class 
holiDay {
  var 
$date$desc$flag;
  function 
holiDay($mon,$day,$year,$desc,$flag false) {
    
$this->desc $desc;
    
$this->flag $flag;
    
$this->date mktime(12,0,0,$mon,$day,$year);
  }
  function 
is_holiday() {
    return 
true;
  }
  function 
flag() {
    return 
$this->flag;
  }
  function 
startFont() {
    return 
"<font color=\"red\">";
  }
  function 
endFont() {
    return 
"</font>";
  }

  function 
mkrow($flagday,$lang 'sv') {
    if (
$this->date >= 0)
      
$ds strftime("%e %B (%A)",$this->date);
    else
      
$ds "<font color=\"blue\">".($lang == 'sv'?'[felaktigt datum]':'[bad date]')."</font>";
    return 
"<tr><td
class=\"nobg\">"
.$this->startFont().$this->desc[$lang].$this->endFont().
      
"</td><td
class=\"nobg\">"
.$ds."</td>".($flagday "<td>".($this->flag() ? "<img
src=\"fl_sm_SWE.gif\" border=0
alt=\"Flaggdag\">" 
"&nbsp;")."</td>" "")."</tr>";
  }
  function 
compare($a,$b) {
    if (
$a->date $b->date)
      return -
1;
    if (
$a->date == $b->date)
      return 
0//strcmp($a->desc, $b->desc);
    
return 1;
  }
}

class 
flagDay extends holiDay {
  function 
flag() {
    return 
true;
  }
  function 
is_holiday() {
    return 
false;
  }
  function 
startFont() {
    return 
"";
  }
  function 
endFont() {
    return 
"";
  }
}

function 
HDcompare($a,$b) {
    if (
$a->date $b->date)
      return -
1;
    if (
$a->date == $b->date)
      return 
0//strcmp($a->desc, $b->desc);
    
return 1;
}
class 
marchDay extends holiDay{
  function 
marchDay($mon,$day,$year,$desc,$flag false) {
    if (
$day <= 31) {        // mars
      
$mon 3$day $day;
    } elseif (
$day <= 31+30) {
      
$mon 4$day $day-31// april
    
} elseif ($day <= 31+30+31) {
      
$mon 5$day $day - (31+30); // maj
    
} elseif ($day <= 31+30+31+30) {
      
$mon 6$day $day - (31+30+31); // juni
    
} else {
      
$mon 3$day $day;    // hmm...
    
}
    
$p get_parent_class($this);
    
parent::$p($mon,$day,$year,$desc,$flag);
  }
}

function 
easterDay($y) {
  
// Se http://aa.usno.navy.mil/faq/docs/easter.html
  
$c floor($y 100);
  
$n $y 19 floor$y 19 );
  
$k floor(( $c 17 ) / 25);
  
$i $c floor($c 4) - floor(( $c $k ) / 3) + 19 $n 15;
  
$i $i 30 floor$i 30 );
  
$i $i floor$i 28 ) * ( floor$i 28 ) * floor29 / ( $i ) )
                * 
floor( ( 21 $n ) / 11 ) );
  
$j $y floor($y 4) + $i $c floor($c 4);
  
$j $j floor$j );
  
$l $i $j;
  
$m floor(( $l 40 ) / 44); // month
  
$d $l 28 31 floor$m ); // day

  
return ($m == $d $d+31);
}


function 
getHolidays($year,$flagdays false) {
  
// Se http://www.jit.se/lagbok/989253t.html och http://www.jit.se/lagbok/982270t.html
// http://www.riksdagen.se/debatt/bet_yttr/dok.asp?dok_id=GS01KU6
  
$easter easterDay($year);
  
// midsommardagen den lördag som infaller under tiden den 20--26 juni
  
$ms getdate(mktime(0,0,0,6,20,$year));
  
$msd 20 + (6-$ms['wday']);
  
// alla helgons dag den lördag som infaller under tiden den 31
  // oktober--den 6 november
  
$ah getdate(mktime(0,0,0,10,31,$year));
  
$ahd 6-$ah['wday'];

  
$hdays = array(new holiDay(1,1,$year,array('sv'=>"Nyårsdagen",
                         
'en'=>'New Year Day'),true),
         new 
holiDay(1,6,$year,array('sv'=>"Trettondagen",
                         
'en'=>'Epiphany')),
         new 
holiDay(5,1,$year,array('sv'=>"Första maj",
                         
'en'=>'May Day'),true),
         new 
marchDay(3,$easter-2,$year,array('sv'=>"Långfredagen",
                              
'en'=>'Good Friday')),
         new 
marchDay(3,$easter,$year,array('sv'=>"Påskdagen",
                            
'en'=>'Easter Day'),true),
         new 
marchDay(3,$easter+1,$year,array('sv'=>"Annandag påsk",
                              
'en'=>'Easter Monday')),
         new 
marchDay(3,$easter+5*7+4,$year,array('sv'=>"Kristi himmelsfärdsdag",
                              
'en'=>'Ascension Day')),
         new 
marchDay(3,$easter+7*7,$year,array('sv'=>"Pingstdagen",
                            
'en'=>'Pentecost Day'),
                  
true),
         new 
holiDay(6,$msd,$year,array('sv'=>"Midsommardagen",
                        
'en'=>'Midsummer Day'),true),
         (
$ahd == ?
          new 
holiDay(10,31,$year,array('sv'=>"Alla helgons dag",'en'=>"All Saint's Day")) :
          new 
holiDay(11,$ahd,$year,array('sv'=>"Alla helgons dag",'en'=>"All Saints' Day"))),
         new 
holiDay(12,25,$year,array('sv'=>"Juldagen",'en'=>'Christmas Day'),true),
         new 
holiDay(12,26,$year,array('sv'=>"Annandag jul",'en'=>'Boxing Day')));
  if (
$year 2005)
    
$hdays[] = new marchDay(3,$easter+7*7+1,$year,array('sv'=>"Annandag pingst",
                            
'en'=>'Whitmonday'));
  else
    
$hdays[] = new holiDay(6,6,$year,array('sv'=>"Sveriges nationaldag och svenska flaggans dag",
                       
'en'=>"Swedish National Day and the Swedish Flag's Day"),
               
true);

  if (
$flagdays) {
    
$fdays = array(new flagDay(1,28,$year,array('sv'=>"Konungens namnsdag",
                        
'en'=>"The King's Name Day")),
           new 
flagDay(3,12,$year,array('sv'=>"Kronprinsessans namnsdag",
                        
'en'=>"The Crown Princess' Name Day")),
           new 
flagDay(4,30,$year,array('sv'=>"Konungens födelsedag",
                        
'en'=>"The King's Birthday")),
           new 
flagDay(7,14,$year,array('sv'=>"Kronprinsessans födelsedag",
                        
'en'=>"The Crown Princess' Birthday")),
           new 
flagDay(8,8,$year,array('sv'=>"Drottningens namnsdag",
                           
'en'=>"The Queen's Name Day")),
           new 
flagDay(10,24,$year,array('sv'=>"FN-dagen",
                         
'en'=>"UN Day")),
           new 
flagDay(11,6,$year,array('sv'=>"Gustav Adolfsdagen",
                        
'en'=>"The Gustaf Adolf Day")),
           new 
flagDay(12,10,$year,array('sv'=>"Nobeldagen",
                         
'en'=>'Nobel Day')),
           new 
flagDay(12,23,$year,array('sv'=>"Drottningens födelsedag",
                         
'en'=>"The Queen's Birthday")));
    if (
$year 2005)
      
$hdays[] = new flagDay(6,6,$year,array('sv'=>"Sveriges nationaldag och svenska flaggans dag",
                         
'en'=>"Swedish National Day and the Swedish Flag's Day"));
    if (
$year == 2010)
      
$fdays[] = new flagDay(9,19,$year,array('sv'=>'Valdagen',
                          
'en'=>'Election day'));
    
$hdays array_merge($hdays,$fdays);
  }
  
usort($hdays,"HDcompare");
  return 
$hdays;
}

function 
show_holidays($year,$flagdays false$lang 'sv') {
  
$hdays getHolidays($year,$flagdays);
  
$rows = array();
  
$hasbad false;
  foreach (
$hdays as $hd) {
    
$rows[] = $hd->mkrow($flagdays,$lang);
    if (
$hd->date <= 0) {
      
$hasbad true;
      break;
    }
  }
  if (
$hasbad) {
    
$last getdate((1<<30)+(1<<29)+((1<<29)-1)); // 2^31-1
    
$lyear $last['year']-1;
    if (
$lang == 'sv')
      return 
'<p style="color: blue">Kanske har du angivit ett för sent
eller för tidigt årtal för detta datorsystem? Prova mellan
'
.date("Y",0).' och '.$lyear.'.</p>';
    else
      return 
'<p style="color: blue">Perhaps you have a too late or too early year for this computer system?  Try one between '.date("Y",0).' and '.$lyear.'.</p>';
  } else {
    return 
'<table border="1" class="nobg">'
      
."<tr><th class=\"nobg\">".($lang == 'sv' ? ($flagdays "Dag":"Helgdag") : ($flagdays 'Day' 'Holiday'))."</th><th
class=\"nobg\">"
.($lang == 'sv' "Datum" 'Date')."</th>".($flagdays ? ($lang == 'sv' "<th>Flaggdag</th>" '<th>Flag day</th>'):"")."</tr>\n"
      
.implode("\n",$rows)
      .
"\n</table>\n";
  }
}

function 
addurlarg($str,$key,$val) {
  if (
preg_match("/(.+)\\?".preg_quote($key)."=([^\\?&]+)(.*)/",$str,$m)) 
    return 
$m[1]."?$key=$val".$m[3];
  elseif (
preg_match("/(.+)&amp;".preg_quote($key)."=([^\\?&]+)(.*)/",$str,$m)) 
    return 
$m[1]."?$key=$val".$m[3];
  elseif (
preg_match("/(.+)&".preg_quote($key)."=([^\\?&]+)(.*)/",$str,$m)) 
    return 
$m[1]."&amp;$key=$val".$m[3];
  elseif (
preg_match("/\\?/",$str))
    return 
$str."&amp;$key=$val";
  else
    return 
$str."?$key=$val";
}

function 
g_or_p($x$default null) {
  if (
array_key_exists($x,$_GET)) // värde från URLen?
    
return $_GET[$x];
  if (
array_key_exists($x,$_POST)) // värde från formulär?
    
return $_POST[$x];
  return 
$default;
}

$year g_or_p('year');
if (empty(
$year) or !checkdate(1,1,$year)) { // inget, eller felaktigt
  
$now getdate(time());
  
$year $now['year'];        // använd innevarande år
}

$flag g_or_p('flagdays');
$flag = !empty($flag);

if (
g_or_p('vcal') == 'yes') {
  
// vill ha det i vCalendar-format!
  
$hdays getHolidays($year,$flag); // Hämta helgdagarna
  
require_once('vcal.php');    // behöver detta bibliotek
  
$hcat g_or_p('hdaycat');    // kategorier
  
$fcat g_or_p('flagcat');
  
$vcvers g_or_p('vcvers',2);    // vCalendar eller iCalendar?
  
$vc = new vCal($hdays,$hcat,$fcat,$vcvers,$lang); // bygg objektet
  
$vc->show_vcal();        // och visa det
  
exit;                // Klart!
}

include(
"header.php");
?>
<body>
<h1><?php echo ($lang == 'sv' 'Allmänna helgdagar' 'Swedish Public Holidays')?></h1>
<p>
<span style="float: right; background-color: white; border: 1px solid red; padding-left: 2px; padding-right: 2px"><?php echo '<a href="'.addurlarg($_SERVER['REQUEST_URI'],"lang",($lang == 'sv'?'en':'sv')).'">'.($lang == 'sv' 'In English, please' 'På svenska tack')?></a></span>
<?php if ($lang == 'sv'): ?>
Detta formulär beräknar <a
href="http://www.riksdagen.se/webbnav/index.aspx?nid=3911&amp;bet=1989:253">svenska
  helgdagar</a> för ett givet år.  <strong>Notera</strong> att helgdagar och flaggdagar kan ändras i framtiden, och att beräkningen sker efter de regler som gäller just nu.
  <?php else: ?>
This form calculates 
  <a href="http://www.riksdagen.se/webbnav/index.aspx?nid=3911&amp;bet=1989:253">Swedish holidays</a> for a given year.  <strong>Please note</strong> that holidays and flag days may change in the future, and that the calculations are done according to the present rules.
  <?php endif; ?>
</p>
<?php
    $now 
getdate();
if ((
$now['year'] == 2008 and ($now['mon'] == and $now['mday'] < 17))) {
 if (
$lang == 'sv') {
 echo 
"<center><a href='http://frapedia.se/wiki/Demonstrationerna_i_Stockholm_den_16_september_2008'><img src='http://stoppafralagen.nu/sites/default/files/banner-16sep.png' alt='Demonstrera mot FRA-lagen 16 september' width='468' height='60'></a></center>";
 }
}
 else if ((
$now['year'] == 2008 and ($now['mon'] == or ($now['mon'] == 10 and $now['mday'] < 12)))) {
   echo 
'<center><a href="http://www.freedom-not-fear.eu/"><img src="http://wiki.vorratsdatenspeicherung.de/images/Webbanner-b_rgb_468x60px.gif" alt="Freedom, not fear!" width="468" height="60"></a></center>';
}
else if ((
$now['year'] == 2005 and ($now['mon'] < 11 or ($now['mon'] == 11 and $now['mday'] < 12)))) {
  if (
$lang == 'sv') {
    echo 
"<span style='float: right'><a href='http://www.nosoftwarepatents.com/se/m/ev50/index.html'><img src='http://www.nosoftwarepatents.com/banners/ev50_2_se.jpg' alt='Rösta för rätten att skriva datorprogram' width='468' height='60'></a></span>";
  } else {
    echo 
"<span style='float: right'><a href='http://www.nosoftwarepatents.com/en/m/ev50/index.html'><img src='http://www.nosoftwarepatents.com/banners/ev50_2_en.jpg' alt='Vote for the right to program' width='468' height='60'></a></span>";
  }
 }
?>
<form action="" method="GET">
<input type="hidden" name="lang" value="<?php echo $lang ?>">
<input type="submit" value="<?php echo ($lang == 'sv' 'Beräkna helgdagar för år' 'Calculate holidays for year')?>">
<input type="text" size="6" name="year" value="<?php echo $year ?>">
<span class="nobg">
  <?php if ($lang == 'sv'): ?>
Visa <a
href="http://www.riksdagen.se/webbnav/index.aspx?nid=3911&amp;bet=1982:270">flaggdagar</a>:&nbsp;
<?php else: ?>
Show <a
href="http://www.riksdagen.se/webbnav/index.aspx?nid=3911&amp;bet=1982:270">flag days</a>:&nbsp;
  <?php endif; ?>
</span><input
type="checkbox" name="flagdays" <?php if ($flag) echo " checked"?>>
</form>

<?php
echo show_holidays($year,$flag,$lang);
?>
<p>
<?php if ($lang == 'sv'): ?>
<strong>Nytt!</strong> Du kan nu få helgdagarna i <a href="http://www.imc.org/pdi/">vCalendar</a> eller <a href="http://www.imc.org/pdi/">iCalendar</a>-format att ladda ner till din PDA eller telefon! <br />[<em>Experimentellt</em> - berätta gärna hur det fungerar, eller om du har förslag till förbättringar!]
   <?php else: ?>
   <strong>New!</strong> You can now get the holidays in <a href="http://www.imc.org/pdi/">vCalendar</a> or <a href="http://www.imc.org/pdi/">iCalendar</a> format, to download to your PDA or telephone! <br />[<em>Experimental</em> - please let me know how it works, or if you have suggestions for improvements!]
   <?php endif; ?>
<ul class="nobg">
<li>
<?php if ($lang == 'sv'): ?>
Klicka <a href="<?php echo addurlarg($_SERVER['REQUEST_URI'],'vcal','yes')?>">här</a> för att få helgdagarna utan "kategorier",
  <?php else: ?>
Click <a href="<?php echo addurlarg($_SERVER['REQUEST_URI'],'vcal','yes')?>">here</a> to get the holidays without "categories",
  <?php endif; ?>
</li>
<li>
<?php if ($lang == 'sv'): ?>
  eller fyll i vilka kategorier du vill använda och klicka "OK":
<?php else: ?>
    or fill in which categories you want to use, and click "OK":
<?php endif; ?>
<form method="post" action="<?php echo preg_replace("/\\?.*$/","",$_SERVER['REQUEST_URI'])?>">
<input type="hidden" name="lang" value="<?php echo $lang ?>" />
<input type="hidden" name="vcal" value="yes" />
<input type="hidden" name="year" value="<?php echo $year ?>" />
  <label for="hdaycat"><?php echo ($lang == 'sv' 'Kategori för helgdagar' 'Category for holidays')?>: </label><input type="text" name="hdaycat" id="hdaycat" />
<?php if ($flag): ?>
<input type="hidden" name="flagdays" value="on" />
   <label for="flagcat"><?php echo ($lang == 'sv' 'Kategori för flaggdagar' 'Category for flag days')?>: </label><input type="text" name="flagcat" id="flagcat" />
<?php endif; ?>
<label for="vcvers">Format: </label>
<select name="vcvers" id="vcvers">
  <option value="1">vCalendar (1.0)</option>
  <option value="2" selected="selected">iCalendar (2.0)</option>
</select>
<input type="submit" value="OK" />
</form>
</li>
</ul>
<p>
<?php
$rq 
strpos($_SERVER['REQUEST_URI'],'?') === false $_SERVER['REQUEST_URI'] : substr($_SERVER['REQUEST_URI'],0,strpos($_SERVER['REQUEST_URI'],'?'));
$src basename($rq,".php")."-source.php";

if (
$lang == 'sv')
  echo 
"(Du kan titta på <a href='".$src."'>källkoden</a> om du vill se hur beräkningarna går till.)";
else
  echo 
"(You can have a look at the <a href='".$src."'>source code</a> if you want to see how the calculations are done.)";

include(
"footer.php");
?>
</body>
</html>