<?php

    lt_include( PLOG_CLASS_PATH."class/plugin/pluginbase.class.php" );
    

    /**
     * Plugin that offers blogtimes for current blog
     * Original Author: Matt Mullenweg http://photomatt.net
     */
    class PluginBlogTimes extends PluginBase
    {

        var $pluginEnabled;
        var $prefix;
        var $backColor;
        var $boxColor;
        var $textColor;
        var $lineColor;
        var $borderColor;
        var $tickColor;
        var $title;
        var $width;
        var $height;
        var $lastDays;
        var $cacheFolder;
    
        function PluginBlogTimes( $source = "" )
        {
            $this->PluginBase($source);
  
            $this->id = "blogtimes";
            $this->author = "Mark Wu";
            $this->desc = "This plugin offers you to show the blogtimes image in your blog.";
            $this->version = "20070301";
  
            // source the neccessary class files
            lt_include( PLOG_CLASS_PATH."class/database/db.class.php" );

            $this->prefix = Db::getPrefix();
            $this->db =& Db::getDb();
            
            $this->locales = Array( "en_UK" , "zh_TW" , "zh_CN" );
            
			if( $source == "admin" )
				$this->initAdmin();
			else
				$this->init();
        }

        function init()
        {
            // register the events we want
            $this->registerNotification( EVENT_POST_POST_ADD );
        }
        
        
        function initAdmin()
        {
            $this->init();
            
            if (defined( "EVENT_POST_ADMIN_PURGE_TEMP_FOLDER" )) {
                // register the events we want
                $this->registerNotification( EVENT_POST_ADMIN_PURGE_TEMP_FOLDER );
            }

            $this->registerAdminAction( "blogtimes", "PluginBlogTimesConfigAction" );
            $this->registerAdminAction( "updateBlogTimesConfig", "PluginBlogTimesUpdateConfigAction" );
            
            $menu =& Menu::getMenu();
            if( !$menu->entryExists( "/menu/controlCenter/manageAppearancePlugins" ))                       
                $this->addMenuEntry( "/menu/controlCenter", "manageAppearancePlugins", "", "", true, false );           
            $this->addMenuEntry( "/menu/controlCenter/manageAppearancePlugins", "BlogTimes", "?op=blogtimes", "" );            
        }

        function register()
        {
            $config =& Config::getConfig();
            $this->cacheFolder = $config->getValue('temp_folder');
            $this->cacheFolder = $this->cacheFolder.'/blogtimes/'.$this->blogInfo->getId();
            if( !File::exists( $this->cacheFolder )) {
                File::createDir( $this->cacheFolder, 0755 );
            }

            $blogSettings = $this->blogInfo->getSettings();
            $this->pluginEnabled = $blogSettings->getValue( "plugin_blogtimes_enabled" );
            $this->backColor = $blogSettings->getValue( "plugin_blogtimes_backcolor" );
            $this->boxColor = $blogSettings->getValue( "plugin_blogtimes_boxcolor" );
            $this->textColor = $blogSettings->getValue( "plugin_blogtimes_textcolor" );
            $this->lineColor = $blogSettings->getValue( "plugin_blogtimes_linecolor" );
            $this->borderColor = $blogSettings->getValue( "plugin_blogtimes_bordercolor" );
            $this->tickColor = $blogSettings->getValue( "plugin_blogtimes_tickcolor" );
            $this->title = $blogSettings->getValue( "plugin_blogtimes_title" );
            $this->width = $blogSettings->getValue( "plugin_blogtimes_width" );
            $this->height = $blogSettings->getValue( "plugin_blogtimes_height" );
            $this->lastDays = $blogSettings->getValue( "plugin_blogtimes_lastdays" );
        }
        
        function isEnabled()
        {
            return $this->pluginEnabled;
        }      
          
		function getPluginConfigurationKeys()
		{
			return( Array(
				Array( "name" => "plugin_blogtimes_enabled", "type" => "boolean" )
			));
		}
		
        /**
         * process the events that we have registered
         *
         * @see PluginBase::process
         * @see PluginManager
         */
        function process( $eventType, $params )
        {
            $validEvent = false;
            
            // Looking for EVENT_POST_POST_ADD  or EVENT_POST_ADMIN_PURGE_TEMP_FOLDER (if defined)
            if (($eventType == EVENT_POST_POST_ADD ) || 
                (defined( "EVENT_POST_ADMIN_PURGE_TEMP_FOLDER" ) && $eventType == EVENT_POST_ADMIN_PURGE_TEMP_FOLDER)) {
                $validEvent = true;
            }

        
            // make sure we're processing the right event!
            if( $validEvent == false) 
            {
                return true;
            }
            
            // Load all of the settings for this blog
            $this->register();
            
            // make sure that the plugin is enabled
			if( !$this->isEnabled())
            {
                return true;
            }
                        
            // Update the Blogtime png
            $this->updateBlogTimePNG();

            return true;
        }
        
        function show() {
            if(!$this->isEnabled())
                return "";
            lt_include( PLOG_CLASS_PATH."class/net/requestgenerator.class.php" );
            $saveFile = $this->cacheFolder."/blogtimes.png";
            $rg =& RequestGenerator::getRequestGenerator( $this->blogInfo );
            $blogtimesTag = "<div align=\"center\"><img src=\"".$rg->getUrl("/".$saveFile)."\" /></div>";
            return $blogtimesTag;                    
        }
        
        function updateBlogTimePNG()
        {
            $saveFile = $this->cacheFolder."/blogtimes.png";  
            
            // constants defining image
            $width = $this->width;
            $height = $this->height;
            $title = $this->title;
            $lastDays = $this->lastDays;
            $fontHeight = imagefontheight(2);
            $fontWidth  = imagefontwidth(2);
            $horzPadding = 5;
            $vertPadding = 5;
            $footerText = "Last $lastDays days";
            $unitText = "Hour of Day";
            
            // create the basic image
            $im = @ImageCreate ($width, $height) or die ('Cannot create a new GD image.');
        
            // define what color to use where
            $color = $this->convertToHexRGB($this->backColor);
            $backColor = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);
            $color = $this->convertToHexRGB($this->boxColor);
            $boxColor  = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);
            $color = $this->convertToHexRGB($this->textColor);
            $textColor = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);
            $color = $this->convertToHexRGB($this->lineColor);
            $lineColor = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);
            $color = $this->convertToHexRGB($this->borderColor);
            $borderColor = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);
            $color = $this->convertToHexRGB($this->tickColor);
            $tickColor = ImageColorAllocate($im, $color['R'], $color['G'], $color['B']);

            # query the db and build the list
            $postTimes = $this->getPostTimes($lastDays);
        
            # calculate how many intervals to show
            $intervals = floor( ($width / 40) );
            if ($intervals >= 24) $i_mod = 1;
            else if ($intervals >= 12) $i_mod = 2;
            else if ($intervals >= 8) $i_mod = 3;
            else if ($intervals >= 6) $i_mod = 4;
            else if ($intervals >= 4) $i_mod = 6;
            else if ($intervals >= 3) $i_mod = 8;
            else if ($intervals >= 2) $i_mod = 16;
            else $i_mod = 24;
        
            # fill the image with the background color
            ImageFill($im, 0, 0, $backColor);
        
            # create a filled  rectangle with a solid border
            $left = $horzPadding; 
            $right = $width - $horzPadding;
            $top = $fontHeight + $vertPadding;
            $bottom = $height - $vertPadding - $fontHeight;
        
            // Show Unit of Measure
            $bottom -= $fontHeight;
        
            ImageFilledRectangle($im, $left,$top,$right,$bottom, $boxColor);
            ImageRectangle($im, $left,$top,$right,$bottom, $borderColor);
        
            # write title and monthtext
            ImageString($im, 2, $left, 0, $title, $textColor);
            $txtWidth = strlen($footerText) * $fontWidth;
            ImageString($im, 2, $right - $txtWidth, 0, $footerText, $textColor);
        
            # add the legend on the bottom
            for ($i = 0; $i <= 23; $i=$i+1)
            {
                if ($i % $i_mod == 0) {
                    $curX = $left + ($right - $left)/24 * $i;
        
                    if ($i > 9) {$strX = $curX - 5;}
                    else        {$strX = $curX - 2;}
        
                    ImageString($im, 2, $strX , $bottom, $i, $textColor);
                    // Show Ticks
                    ImageLine($im, $curX, $bottom, $curX, $bottom - 5, $tickColor);
                }
            }
            ImageString($im, 2, $right - 5, $bottom,  0, $textColor);
            
            // Show Unit of Measure
            $curX = ($right + $left) / 2 - ($fontWidth * strlen($unitText)/2);
            $curY = $bottom + $fontHeight + 2;
            ImageString($im, 2, $curX, $curY, $unitText, $textColor);
        
            # now we draw the lines for each post
            # the post times should be in terms of # of minutes since midnight
            $arrCount = count($postTimes);
            for ($i = 0; $i < $arrCount; $i++)
            {
                # make sure postTime is between 0 and 1439
                $curPostTime = abs($postTimes[$i]) % 1440; 
                
                # calculate the horz pos inside box              
                $curX = $left + ($right - $left)/1440 * $curPostTime;    # 1440 minutes per day
        
                # draw the post line
                ImageLine($im, $curX, $bottom, $curX, $top, $lineColor);
            }
        
            # save the file to disk in PNG format 
            ImageColorTransparent($im, $backColor);
            ImagePNG ($im,$saveFile);
            File::chMod($saveFile, 0644);
        }
        
        # This function will query the db for all the posts in last x days
        # and build an array of # of minutes since midnight for each post
        function getPostTimes($lastDays = 30)
        {
            lt_include( PLOG_CLASS_PATH.'class/data/timestamp.class.php' );
            $blogId = $this->blogInfo->getId();
            
            //
            // if there's a time difference applied to all dates, then we'd better
            // calculate it here!!
            //
            $blogSettings = $this->blogInfo->getSettings();
            $timeDiff = $blogSettings->getValue( 'time_offset' );


            $query = "SELECT date FROM ".$this->prefix."articles";
            $query .= " WHERE blog_id = ".$blogId." AND status = 1";
            $query .= " AND (TO_DAYS(CURRENT_DATE) - TO_DAYS(date)) <= '$lastDays'";
            $query .= " ORDER BY date ASC";

            $result = $this->db->Execute( $query );

            if( !$result )
                return false;

            $postTimes = Array();
            while( $row = $result->FetchRow()) {
                // we can use this auxiliary function to help us...
                $date = new Timestamp( Timestamp::getDateWithOffset( 
                                           $row['date'], 
                                           $timeDiff ));
                
               array_push( $postTimes, ($date->getHour()*60)+$date->getMinute());
            }
            
            return $postTimes;
        }
        
        function convertToHexRGB( $colorCode )
        {
            sscanf($colorCode, "#%2x%2x%2x", $red, $green, $blue);
            
            $color = Array();
            $color['R'] = $red;
            $color['G'] = $green;
            $color['B'] = $blue;
            
            return $color;
        }
    }
?>
