<?php

/*
Plugin Name: Colhour
Plugin URI: http://burnfield.com/martin
Version: 0.3.3
Author: Martin Str&ouml;m
Author URI: http://burnfield.com/martin
Description: Enables the page to have colors generated by the <a href="http://harald.net/colhour">Colhour</a> system.
*/

/* --------------------------------------------------------------------------------
 * Colhour class
 * -------------------------------------------------------------------------------- */

class Colhour {
    
    
// Color table
    
var $_colors = array (
        
        
'year' => array(
            
"8300FF", "3F00FF", "3F00FF", "0081FF", "00FFFB", "00FF81", 
            
"00FF02", "7DFF00", "FCFF00", "FF8A00", "FF1300", "E80030", 
        ),

        
'month' => array(
            
"8200FF", "6600FF", "4A00FF", "3000FF", "1700FF", "000AFF", 
            
"003EFF", "008AFF", "00A6FF", "00F0FF", "00FFF3", "00FFC1", 
            
"00FF8D", "00FF5A", "00FF2C", "0BFF00", "3EFF00", "71FF00",   
            
"89FF00", "D9FF00", "FFF400", "FFC400", "FF9300", "FF6300",
            
"FF3000", "FF0000", "E40037", "CA006D", "B000A2", "9C00CC", 
            
"8F00E7",
        ),

        
'day' => array(
            
"8300FF", "6200FF", "3F00FF", "1F00FF", "3F00FF", "0043FF", 
            
"0081FF", "00C3FF", "00FFFB", "00FFBF", "00FF81", "00FF3F", 
            
"00FF02", "3DFF00", "7DFF00", "BCFF00", "FCFF00", "FFC400", 
            
"FF8A00", "FF4C00", "FF1300", "E80030", "E80030", "C70074", 
        ),

        
'hour' => array(
            
"8200FF", "7400FF", "6600FF", "5900FF", "4A00FF", "3D00FF", 
            
"3000FF", "2300FF", "1700FF", "0700FF", "000AFF", "0026FF", 
            
"003EFF", "0058FF", "008AFF", "008AFF", "00A6FF", "00BEFF", 
            
"00F0FF", "00FFF3", "00FFF3", "00FFDE", "00FFC1", "00FFA7", 
            
"00FF8D", "00FF75", "00FF5A", "00FF42", "00FF2C", "00FF0F", 
            
"0BFF00", "25FF00", "3EFF00", "56FF00", "71FF00", "89FF00", 
            
"89FF00", "BFFF00", "D9FF00", "F3FF00", "FFF400", "FFDB00", 
            
"FFC400", "FFA800", "FF9300", "FF7800", "FF6300", "FF4900", 
            
"FF3000", "FF1900", "FF0000", "F30018", "E40037", "D8004F", 
            
"CA006D", "BD0087", "B000A2", "A200C0", "9C00CC", "8F00E7",
        ),
        
        
'minute' => array(
            
"8200FF", "7400FF", "6600FF", "5900FF", "4A00FF", "3D00FF", 
            
"3000FF", "2300FF", "1700FF", "0700FF", "000AFF", "0026FF", 
            
"003EFF", "0058FF", "008AFF", "008AFF", "00A6FF", "00BEFF", 
            
"00F0FF", "00FFF3", "00FFF3", "00FFDE", "00FFC1", "00FFA7", 
            
"00FF8D", "00FF75", "00FF5A", "00FF42", "00FF2C", "00FF0F", 
            
"0BFF00", "25FF00", "3EFF00", "56FF00", "71FF00", "89FF00", 
            
"89FF00", "BFFF00", "D9FF00", "F3FF00", "FFF400", "FFDB00", 
            
"FFC400", "FFA800", "FF9300", "FF7800", "FF6300", "FF4900", 
            
"FF3000", "FF1900", "FF0000", "F30018", "E40037", "D8004F", 
            
"CA006D", "BD0087", "B000A2", "A200C0", "9C00CC", "8F00E7",
        ),
    );
    
    
// Hard coded UNIX timestamps
    
var $_timestamps = array(
        
'second' => 1,
        
'minute' => 60,
        
'hour'   => 3600,
        
'day'    => 86400,
        
'month'  => 2635200, // 30.5 days
        
'year'   => 31536000,
    );
        
    
// Part specific data
    
var $_info = array(    
        
'year'   => array("Y-1-1", "month", "m"),
        
'month'  => array("Y-m-1 0:0:0", "day", "j"),
        
'day'    => array("Y-m-d H", "hour", "H"),
        
'hour'      => array("Y-m-d H:i", "minute", "i"),
        
'minute' => array("Y-m-d H:i:s", "second", "s") // the blending won't work for minutes
    
);
    
    
// Converts a hex number to RGB 
    
function _hex2RGB($hexstr) {
        
$int = hexdec($hexstr);
        return array(
            
'r' => 0xFF & ($int >> 0x10),
            
'g' => 0xFF & ($int >> 0x8),
            
'b' => 0xFF & ($int)
        );
    }

    
// Blends (fades) between two colors
    
function _blendRGB($c1, $c2, $t) {
        
// $t must be in range 0...1
        
if ($t < -1) $t = -1;
        else if (
$t > 1) $t = 1;
        if (
$t < 0) $t = 1 + $t;

        
// convert colors from hex to rgb values
        
$c1 = $this->_hex2RGB($c1);
        
$c2 = $this->_hex2RGB($c2);

        
// transform
        
$ct = ($c1['r'] + ($c2['r'] - $c1['r']) * $t) << 16 | 
                    (
$c1['g'] + ($c2['g'] - $c1['g']) * $t) << 8 | 
                    (
$c1['b'] + ($c2['b'] - $c1['b']) * $t); 

        return 
"#".str_pad(dechex($ct), 6, "0", STR_PAD_LEFT);
    }

    
// Returns the current color for given type. If no timestamp is given it'll use the current
    
function getColor($type="minute", $timestamp=NULL) {
        
$info = $this->_info[$type];

        
// Fix timestamp arg
        
if (!$timestamp) {
            
$timestamp = time();
        }

        
// Calculate ratio
        
$ms_this = strtotime(date($info[0], $timestamp)); 
        
$ms_next = $ms_this + $this->_timestamps[$info[1]];
        
$ratio = (($ms_next - $ms_this) == 0)? 0 : ($timestamp - $ms_this) / ($ms_next - $ms_this);

        
// Get colors to blend between
        
$index = (int) date($info[2], $timestamp);
        
$c1 = $this->_colors[$type][$index];
         
$c2 = $this->_colors[$type][$index + 1];

        
// Debugging
        /*print "<pre> :::: ".strtoupper($type)." :::: \n\n"; 
         print_r(array(
                 "ms_this  " => $ms_this." (".date("Y-m-d H:i:s", $ms_this).")", 
                 "ms_next  " => $ms_next." (".date("Y-m-d H:i:s", $ms_next).")", 
                 "timestamp" => $timestamp." (".date("Y-m-d H:i:s", $timestamp).")", 
                 "index" => $index, 
                 "ratio" => $ratio
         )); 
        print "</pre>";*/
        
        
return $this->_blendRGB($c1, $c2, $ratio);
    }

    
// Prints a html spectrum with all colors in given type
    
function printHTMLSpectrum($type="minute") {
        
$color = $this->_colors[$type];
        
$html = '<div id="_colhour_spectrum" style="-border: 1px solid #000;">';
        foreach (
$color as $c) {
            
$html .= '<div style="width: 25px; height: 25px; background: #'.$c.'; float: left;"></div>';
        }
        
$html .= '<p style="clear: both; padding: 0; margin: 0; height: 0.1%;"></p></div>';
        echo 
$html;
    }
    
    
// Prints a html spectrum with all colors for every type
    
function printHTMLSpectra() {
        foreach (
$this->_colors as $name => $value) {
            echo 
"$name";    
            
$this->printHTMLSpectrum($name);
        }
    }
    
    
// Returns an array containing the different types supported
    
function getTypes() {
        return 
array_keys($this->_colors);
    }
}


/* --------------------------------------------------------------------------------
 * Plugin class
 * -------------------------------------------------------------------------------- */

class ColhourPlugin extends Colhour {
    
    
// Prints the CSS-rules with colhour replaces colors
    
function getCSS() {
        
?>
    <style type="text/css" media="screen">
    /* <![CDATA[ */

    <?php
    $css 
= "";
    foreach (
$this->getTypes() as $type) {
        
$rule = get_option("colhour_css_$type")."\n";
        if (
trim($rule) == "") continue;
        
$css .= str_replace("%colhour%", $this->getColor($type), $rule);

    }
    echo 
preg_replace("/\n\s*/", "\n\t", $css);
    
?>

    /* ]]> */
    </style>
        <?php
    
}
    
    
// Set default options
    
function setDefaultOptions() {
        foreach (
$this->getTypes() as $type) {
            
add_option("colhour_css_$type", "");
        }
    }

    
// Adds the Colhour option page to WP's admin
    
function addOptionsPage() {
        if (
function_exists('add_options_page')) {
            
add_options_page("Colhour", "Colhour", 5, 'ColhourTab', array(&$this, 'optionsPage'));
        }
    }

    
// Generates the page for editing the options
    
function optionsPage() {
        
$this->setDefaultOptions();

        if (isset(
$_POST['info_update'])) { 
            
?><div id="message" class="updated fade">
                <p><strong><?php 
                    
foreach ($this->getTypes() as $type) {
                        
update_option("colhour_css_$type", $_POST["colhour_css_$type"]);
                    }
                    
_e('Colhour options  saved.')
                
?></strong></p>
            </div>
        <?php } ?>

        <div class="wrap">
            <form method="post">
                <h2>Colhour Options</h2>

                <p>The CSS rules are divided into different types by how long time the spectrum needs to start over from the beginning each time.</p>
                <p>Use <code>%colhour%</code> (without any "<code>#</code>") as a placeholder for the color generated by Colhour.</p>

                <p>
                    <code>
                        /* Examples */<br />
                        body {background: %colhour%};<br />
                        #header {border-bottom: %colhour%;}<br />
                        p.colhour {color: %colhour%;}
                    </code>
                </p>

                <p><a href="http://harald.net/colhour">Read more about Colhour.</a></p>

                <fieldset id="colhour_options" class="options">
                    <?php 
                    
foreach (array_reverse($this->getTypes()) as $type): 
                        
$value = get_option("colhour_css_$type");
                        
$rows_add = 2;
                        
$rows = (trim($value) == "")? $rows_add : count(preg_split("%\r\n|\r|\n%", $value)) + $rows_add;
                        
?>
                        <p>
                            <label for="colhour_css">Resets after one <strong><?php echo $type ?></strong></label>
                            <textarea name="colhour_css_<?php echo $type ?>" 
                                    id="colhour_css_<?php echo $type ?>" style="width: 98%;" rows="<?php echo $rows ?>" 
                                    cols="50" onfocus="this.rows += <?php echo $rows_add ?>;" 
                                    onblur="this.rows = ((this.value == '')? <?php echo $rows_add ?> : (this.value.split(/\r\n|\r|\n/).length) + <?php echo $rows_add ?>);"><?php echo $value ?></textarea>
                        </p>
                    <?php endforeach ?>        
                </fieldset>            

                <div class="submit">
                      <p><input type="submit" name="info_update" value="<?php _e('Update Colhour Options') ?> &raquo;" /></p>
                </div>

            </form>
        </div>
        <?php
    
}

    
// Hooks in the plugin to the site's head and admin menu
    
function addHooks() {
        if (
strpos($_SERVER['PHP_SELF'], 'wp-admin') === FALSE) {
            
add_action('wp_head', array(&$this, 'getCSS'));
        } else {
            
add_action('admin_menu', array(&$this, 'addOptionsPage'));
        }
    }

    
// Constructor
    
function ColhourPlugin() {
        
$this->setDefaultOptions();
        
$this->addHooks();
    }
}


/* --------------------------------------------------------------------------------
 * Initialization
 * -------------------------------------------------------------------------------- */

$colhourPlugin = new ColhourPlugin();

// TM_PREVIEW_URL=http://projects/Work/wp-admin/options-general.php?page=ColhourTab

?>