<?php
/**********************************************************************
* OSAKA UNLIMITED WORDPRESS THEME 
* (Ideal For Business And Personal Use: Portfolio or Blog)     
* 
* File name:   
*      cp_classes.php
* Brief:       
*      Part of theme control panel. Definition of global utility classes
* Author:      
*      DigitalCavalry
* Author URI:
*      http://themeforest.net/user/DigitalCavalry
* Contact:
*      digitalcavalry@gmail.com 
***********************************************************************/

/*********************************************************** 
* Class name:
*    DCC_MetaPageBuilder
* Descripton:
*    Implementation of abstract class DCC_MetaPageBuilder 
***********************************************************/
abstract class DCC_MetaPageBuilder extends DCC_BasicTools
{
    /*********************************************************** 
    * Public members
    ************************************************************/    
    public $_opt_name; // meta box name
    public $_title; // title for meta box
    public $_slug; // title as slug
    public $_post_type; // page or post
    public $_closed; // meta box closed or open in default
    
    /*********************************************************** 
    * Public functions
    ************************************************************/    
    abstract public function display();
    abstract public function createStandardMetaOjectData();
    abstract public function createStandardCellOjectData();
    abstract public function save($id); 
    
    public function adminMenu() 
    {   
        add_meta_box($this->_slug, $this->_title, array(&$this, 'display'), $this->_post_type, 'normal', 'high' );    
        
        // Turned off, because after saving/updating post, the box is rendered as closed and this make some ergonimic problem in post editing        
        $AUTO_CLOSED_BOXS = false;
        
        if($AUTO_CLOSED_BOXS)
        {
            if($this->_post_type == 'post')
            {
                add_filter( 'postbox_classes_post_'.$this->_slug, array(&$this, 'add_my_meta_box_classes'));    
            } else
            {
              add_filter( 'postbox_classes_page_'.$this->_slug, array(&$this, 'add_my_meta_box_classes'));          
            }
        }
    }    
    
    public function add_my_meta_box_classes($classes=array())      
    {   
        if(!in_array('closed', $classes) and $this->_closed) { $classes[] = 'closed'; }
        return $classes;
    }             
    
    public function getMetaTopSavePanel($btn_value='Update', $echo=false)
    {
        $out = '';
        $out .= '<div class="top-save-panel">';
            $out .= '<input id="publish" class="dc-cms-submit-btn-primary" type="submit" name="save" value="'.$btn_value.'"> ';    
        $out .= '</div>';
        if($echo) { echo $out; } else { return $out; }
    }
    
    public function getMetaBottomSavePanel($btn_value='Update', $echo=false)
    {
        $out = '';
        $out .= '<div class="bottom-save-panel">';
            $out .= '<input id="publish" class="dc-cms-submit-btn-primary" type="submit" name="save" value="'.$btn_value.'"> ';    
        $out .= '</div>';
        if($echo) { echo $out; } else { return $out; }
    }        
}

/*********************************************************** 
* Class name:
*    DCC_PrivateSeoMeta
* Descripton:
*    Implementation of abstract class DCC_PrivateSeoMeta 
***********************************************************/
class DCC_PrivateSeoMeta
{
    public function __construct()
    {
        $this->_name = '';    
        $this->_content = '';
        $this->_active = true;
    }
    
    public $_url;  
    public $_display;    
    public $_active;
    
    public static function getHTMLMeta($meta=null, $index)
    {
        $out = '';
        
        $out .= '<div class="meta-item">';
            $out .= '<input type="hidden" class="dc-idx" value="'.$index.'" />';                
            $out .= '<div class="delete-btn"></div>';
            
            $out .= '<span class="dc-cms-control-top-label-nomargin">Name</span>';
            $out .= '<input type="text" class="dc-cms-control-300" value="'.$meta->_name.'" name="dc-seo-private-meta-'.$index.'-name" />'; 

            $out .= '<span class="dc-cms-control-top-label">Content</span>';
            $out .= '<textarea class="dc-cms-control-wide dc-cms-control-textarea dc-cms-control-h-60" name="dc-seo-private-meta-'.$index.'-content" />'.$meta->_content.'</textarea>';
            
            $tools = new DCC_BasicTools();
            $out .= $tools->getStdInputsFieldStart();
                $out .= '<input type="checkbox" name="dc-seo-private-meta-'.$index.'-active" '.$tools->attrChecked($meta->_active).' /> Active';
            $out .= $tools->getStdInputsFieldEnd();
            
        $out .= '</div>';
        
        return $out;    
    }
}

/*********************************************************** 
* Class name:
*    DCC_MetaMultiple
* Descripton:
*    Implementation of abstract class DCC_MetaMultiple 
***********************************************************/
abstract class DCC_MetaMultiple extends DCC_BasicTools
{
    /*********************************************************** 
    * Public members
    ************************************************************/    
    public $_names; // meta box name
    public $_std; // array of standard meta values
    public $_title; // title for meta box
    public $_slug; // title as slug
    public $_post_type; // page or post
    public $_closed; // meta box closed or open in default
    public $_context; // meta box content
    public $_side_boxes; // array of side meta boxes
    
    /*********************************************************** 
    * Public functions
    ************************************************************/    
    abstract public function display();
    
    public function adminMenu() 
    {   
        add_meta_box($this->_slug, $this->_title, array(&$this, 'display'), $this->_post_type, 'normal', 'high' );    
        
        // Turned off, because after saving/updating post, the box is rendered as closed and this make some ergonimic problem in post editing        
        $AUTO_CLOSED_BOXS = false;
        
        if($AUTO_CLOSED_BOXS)
        {
            if($this->_post_type == 'post')
            {
                add_filter( 'postbox_classes_post_'.$this->_slug, array(&$this, 'add_my_meta_box_classes'));    
            } else
            {
              add_filter( 'postbox_classes_page_'.$this->_slug, array(&$this, 'add_my_meta_box_classes'));          
            }
        }
    }    
    
    public function add_my_meta_box_classes($classes=array())      
    {   
        if(!in_array('closed', $classes) and $this->_closed) { $classes[] = 'closed'; }
        return $classes;
    }         
    
    public function save($post_id)
    {
        global $post;
          
        if(isset($_POST['post_type']) and 'page' == $_POST['post_type']) 
        {  
            if(!current_user_can('edit_page', $post_id)) 
            { 
                return $post_id; 
            } 
        } else 
        {  
            if(!current_user_can('edit_post', $post_id))
            { 
                return $post_id; 
            } 
        }  

        $data = array();
        $count = count($this->_names);
        if(isset($_POST[($this->_names[0].'_cbox')]))
        {        
            for($i = 1; $i < $count; $i++)
            {
                $checkbox = strstr($this->_names[$i], '_cbox');
                $as_array = strstr($this->_names[$i], '_arr'); 
                if($checkbox !== false) { $checkbox = true; }
                if($as_array !== false) { $as_array = true; }
                
                if($checkbox)
                {
                   $data[$this->_names[$i]] = isset($_POST[$this->_names[$i]]) ? true : false;
                } else 
                if($as_array)
                {
                   $data[$this->_names[$i]] = isset($_POST[$this->_names[$i]]) ? $_POST[$this->_names[$i]] : array();
                } else 
                {                                                
                   $data[$this->_names[$i]] = $_POST[$this->_names[$i]]; 
                }
            }    

            update_post_meta($post_id, $this->_names[0], $data);                    
        } else
        {
           $t_value = get_post_meta($post_id, $this->_names[0], true);
           if($t_value != '')
           {
                $t_value[($this->_names[0].'_cbox')] = false;
                update_post_meta($post_id, $this->_names[0], $t_value);    
           }  
        }
    }
    
    public function initDisplay()
    {
        // decalre global variable which contain post data
        global $post; 
        
        // get meta box value
        $value = get_post_meta($post->ID, $this->_names[0], true);        
        // if meta box dont have value set it to standard
        if('' == $value) { $value = $this->_std; }

        return $value;        
    }
    
    public function getMetaTopSavePanel($btn_value='Update', $echo=false)
    {
        $out = '';
        $out .= '<div class="top-save-panel">';
            $out .= '<input id="publish" class="dc-cms-submit-btn-primary" type="submit" name="save" value="'.$btn_value.'"> ';    
        $out .= '</div>';
        if($echo) { echo $out; } else { return $out; }
    }
    
    public function getMetaBottomSavePanel($btn_value='Update', $echo=false)
    {
        $out = '';
        $out .= '<div class="bottom-save-panel">';
            $out .= '<input id="publish" class="dc-cms-submit-btn-primary" type="submit" name="save" value="'.$btn_value.'"> ';    
        $out .= '</div>';
        if($echo) { echo $out; } else { return $out; }
    }        
}

/*********************************************************** 
* Class name:
*    DCC_Sidebar
* Descripton:
*    Implementation of single sidebar object    
***********************************************************/
class DCC_Sidebar
{
    /*********************************************************** 
    * Constructor
    ************************************************************/
    public function __construct($name='') 
    {
        $this->_name = $name;
        $this->_id = time(); 
        $this->_childs = array($this->_id => true);       
    } // constructor
    
    /*********************************************************** 
    * Public memebers
    ************************************************************/    
    public $_name;
    public $_id;    
    public $_childs;
    
    public function inChilds($id)
    {
        $onlist = false;
        if(is_array($this->_childs))
        {
            foreach($this->_childs as $sid_id => $use)
            {
                if($id == $sid_id)
                {
                    $onlist = true;
                    break;
                }
            }
        }
        
        return $onlist;
    }     
}

class DCC_PageSidebars
{
    /*********************************************************** 
    * Constructor
    ************************************************************/
    public function __construct() 
    {                      
        $this->left = CMS_NOT_SELECTED;        
        $this->right = CMS_NOT_SELECTED;
    } // constructor 
    
    public $left;
    public $right;
}

class DCC_ExportDataCMSObject
{
    /*********************************************************** 
    * Constructor
    ************************************************************/
    public function __construct() 
    {                      
        $this->name = '';        
        $this->version = '';
        $this->data = '';
    } // constructor 
    
    public $name;
    public $version;
    public $data;
}

/*********************************************************** 
* Class name:
*    DCC_StandardIcon
* Descripton:
*    Implementation of single DCC_StandardIcon object    
***********************************************************/
class DCC_StandardIcon extends DCC_BasicTools
{
    /*********************************************************** 
    * Constructor
    ************************************************************/
    public function __construct($args=array()) 
    {
        $def = array(
            'desc' => 'Icon description', 
            'name' => 'Icon name',  
            'imgurl' => '', 
            'imgurl_hover' => '',
            'url' => '',
            'hide' => false,
            'target_blank' => true,
            'hovered' => false
        );
        
        $args = $this->combineArgs($def, $args);                
        
        $this->_imgurl = $args['imgurl'];
        $this->_imgurl_hover = $args['imgurl_hover']; 
        $this->_target_blank = $args['target_blank'];
        $this->_hide = $args['hide'];
        $this->_url = $args['url'];
        $this->_name = $args['name'];; 
        $this->_desc = $args['desc'];     
        $this->_hovered = $args['hovered'];   
    }
    
    /*********************************************************** 
    * Public memebers
    ************************************************************/    
    public $_imgurl;
    public $_hide;
    public $_url;  
    public $_name;
    public $_desc; 
    public $_hovered;
    public $_imgurl_hover;
    public $_target_blank;        
}



/*********************************************************** 
* Class name:
*    DCC_Twitter
* Descripton:
*    Implementation of class DCC_Twitter 
***********************************************************/
class DCC_TwitterUserData
{
    public function __construct()
    {
        
    } 
    
    public $profile_image_url = '';
    public $screen_name = '';
    public $followers_count = 0;
    public $statuses_count = 0;      
}    

class DCC_TwitterTweetData
{
    public function __construct()
    {
        
    }     
    
    public $created_at = '';
    public $text = '';
    public $source = '';  
}

class DCC_TwitterUserTimelineData
{
    public function __construct()
    {
        
    }   
    
    public $tweets = array();     
}    
 
class DCC_Twitter extends DCC_BasicTools
{
    public function __construct($args=array())
    {
        $def = array(
            'consumer_key' => '',
            'consumer_secret' => '',
            'token_key' => '',
            'token_secret' => ''            
        );    
        
        $args = $this->combineArgs($def, $args);
        
        $this->_consumer_key = $args['consumer_key'];
        $this->_consumer_secret = $args['consumer_secret'];
        $this->_token_key = $args['token_key'];
        $this->_token_secret = $args['token_secret'];
    }
    
    private $_consumer_key = '';
    private $_consumer_secret = '';
    private $_token_key = '';
    private $_token_secret = '';
    private $_connection = null;
    private $_httpCode;
    
    public function getUserData($args=array())
    {
        $def = array(
            'screen_name' => ''
        );
        
        $args = $this->combineArgs($def, $args);
        
        $this->makeConnection();
        $content = $this->_connection->get("users/show", array('screen_name' => $args['screen_name'])); 

        $user = false;
        if($this->_connection->http_code == 200)
        {
           $obj = new DCC_TwitterUserData();
           
           $obj->screen_name = $content->screen_name;
           $obj->profile_image_url = $content->profile_image_url;
           $obj->statuses_count = $content->statuses_count;
           $obj->followers_count = $content->followers_count;
           
           $user = $obj;      
        }        
    
        return $user;
    }

    public function getUserTimelineData($args=array())
    {
        $def = array(
            'screen_name' => '',
            'count' => 8
        );
        
        $args = $this->combineArgs($def, $args);
        
        $this->makeConnection();
        $content = $this->_connection->get("statuses/user_timeline", array('screen_name' => $args['screen_name'], 'count' => $args['count']));  
        
        $timeline = false;
        if($this->_connection->http_code == 200)
        {
           $obj = new DCC_TwitterUserTimelineData();
        
           if(is_array($content))
           {
               foreach($content as $t)
               {
                    $t_obj = new DCC_TwitterTweetData();
                    
                    $t_obj->created_at = $t->created_at;
                    $t_obj->source = $t->source;
                    $t_obj->text = $t->text;
                    
                    array_push($obj->tweets, $t_obj);    
               }
               
               $timeline = $obj;               
           }           
        }        
        
        return $timeline;
    }
    
    private function makeConnection()
    {
        if($this->_connection === null)
        {
            $this->_connection = new TwitterOAuth(
                $this->_consumer_key, 
                $this->_consumer_secret, 
                $this->_token_key,  
                $this->_token_secret);    
        }    
    }
    
    public function getHTTPCode()
    {
        $this->_connection->http_code;
    }
    
    public function twitterify($text) 
    {
        $text = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)[a-z0-9A-Z]*#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $text);
        $text = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)[a-z0-9A-Z]*#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $text);
        $text = preg_replace("/@(\w+)/", "<a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $text);
        $text = preg_replace("/#(\w+)/", "<a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $text);
        return $text;
    }     
    
}  

/*********************************************************** 
* Class name:
*    DCC_ThemeCMSSettingsManager
* Descripton:
*    Implementation of class DCC_ThemeCMSSettingsManager 
***********************************************************/
class DCC_ThemeCMSSettingsManager extends DCC_BasicTools
{
    public function __construct()
    {  
    }   
    
    public $_log = '';   
    
    public function exportDataToZip($args=array())
    {
        $result = false;
        $def = array(
            'export_path' => '',
            'filename' => '',
            'clear_twitter' => false,
            'clear_tracking' => false,
        );
        $args = $this->combineArgs($def, $args);
        
        $is_dir = is_dir($args['export_path']);
        if($is_dir and $args['filename'] != '')
        {
                        
            if(class_exists('ZipArchive'))
            {
                $zip = new ZipArchive;
                $res = $zip->open($args['export_path'].'/'.$args['filename'], ZipArchive::CREATE | ZipArchive::OVERWRITE);
                if($res == true)
                {            
                    $general_content = serialize(GetDCCPI()->getIGeneral()->getExportedData(
                        array(
                            'clear_twitter' => $args['clear_twitter'],
                            'clear_tracking' => $args['clear_tracking'],
                        )));
                    $zip->addFromString('general.txt', $general_content);
                    
                    $font_content = serialize(GetDCCPI()->getIFont()->getExportedData());   
                    $zip->addFromString('font.txt', $font_content);
                    
                    $zip->close();
                    
                    $result = true;
                }
            }                        
                                    
        }
        
        return $result;        
    }
    
    public function importDataFromZip($args=array())
    {
        $result = false;
        $this->_log = '';
        
        $def = array(
            'zip_file_path' => '',
            'extract_path' => '',       
        );
        $args = $this->combineArgs($def, $args);
    
        $this->addLog('Checking file.. ');    
        $is_file = is_file($args['zip_file_path']);
        if($is_file) { $this->addLog('OK', true); } else { $this->addLog('Error', true); }
        
        $this->addLog('Checking extract dir.. ');
        $is_dir = is_dir($args['extract_path']);
        if($is_dir) { $this->addLog('OK', true); } else { $this->addLog('Error', true); }
        
        if($is_file and $is_dir)
        {
            $this->addLog('Opening ZIP archive.. ');
            if(class_exists('ZipArchive'))
            {
                $zip = new ZipArchive;
                if($zip->open($args['zip_file_path']) === true) 
                {
                    $this->addLog('OK', true); 
                    $this->addLog('Extracting archive.. ');
                    if($zip->extractTo($args['extract_path'], array('general.txt', 'font.txt')) === true)
                    {
                        $this->addLog('OK', true);
                        
                        $handle = false;
                        $file_content = '';
                        $file_path = '';
                        $file_size = 0;
                        $file_name = '';
                        
                        $general_status = false;
                        $font_status = false; 
                        
                        // general cms
                        $file_name = 'general.txt';
                        $file_path = $args['extract_path'].'/'.$file_name;                        
                        
                        $this->addLog('Start to reading general settings.. OK', true);                        
                        $this->addLog('Looking for '.$file_name.' file.. ');                      
                        
                        if(is_file($file_path))
                        {
                            $file_size = filesize($file_path);                        
                            $handle = fopen($file_path, 'r');
                            
                            if($handle)
                            {
                                $this->addLog('OK', true);
                                $this->addLog('File size '.$file_size.' bytes.. OK', true);                            
                                
                                $file_content = fread($handle, $file_size);
                                $file_content = unserialize($file_content);
                                
                                $r = GetDCCPI()->getIGeneral()->setImportedData($file_content);

                                if($r['status'])
                                {
                                    $this->addLog('Updating.. '.$r['message'], true);
                                    $general_status = true;    
                                } else
                                {
                                    $this->addLog('Updating.. '.$r['message'], true);    
                                }
                                
                                fclose($handle);
                            } else { $this->addLog('Error', true); }
                        } else 
                        { 
                            $this->addLog('Error', true);                            
                        }
                        
                        // font cms 
                        $file_name = 'font.txt'; 
                        $file_path = $args['extract_path'].'/'.$file_name;                        
                        
                        $this->addLog('Start to reading font settings.. OK', true);
                        $this->addLog('Looking for '.$file_name.' file.. ');                                                 
                        
                        if(is_file($file_path))
                        {                            
                            $file_size = filesize($file_path);                        
                            $handle = fopen($file_path, 'r');                         
                            
                            if($handle)
                            {
                                $this->addLog('OK', true);
                                $this->addLog('File size '.$file_size.' bytes.. OK', true);                            
                                
                                $file_content = fread($handle, $file_size);
                                $file_content = unserialize($file_content);
                                
                                $r = GetDCCPI()->getIFont()->setImportedData($file_content);

                                if($r['status'])
                                {
                                    $this->addLog('Updating.. '.$r['message'], true);
                                    $font_status = true;    
                                } else
                                {
                                    $this->addLog('Updating.. '.$r['message'], true);    
                                }
                                
                                fclose($handle);
                            } else { $this->addLog('Error', true); }    
                        } else
                        {
                            $this->addLog('Error', true);                         
                        }                    
                        
                        if($general_status and $font_status)
                        {
                            $result = true; 
                        }           
                    } else
                    {
                        $this->addLog('Error', true);    
                    }
                    
                    $zip->close();
                    
                } else { $this->addLog('Error', true); }
            } else { $this->addLog('Error', true); }            
        }
        
        return $result;
    }
    
    private function addLog($text='', $br=false)
    {
        $this->_log .= $text;
        if($br) { $this->_log .= '<br />'; }
    }    
}  

/*********************************************************** 
* Class name:
*    DCC_NGGImage
* Descripton:
*    Implementation of class DCC_NGGImage 
***********************************************************/
class DCC_NGGImage
{
    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($pid, $imageURL, $thumbURL, $width, $height, $thumbcode, $description, $alttext, $imagedate)
    {
        $this->_pid = $pid;
        $this->_imageURL = $imageURL;
        $this->_thumbURL = $thumbURL;
        $this->_width = $width;
        $this->_height = $height;
        $this->_thumbcode = $thumbcode;
        $this->_description = $description;
        $this->_alttext = $alttext;
        $this->_imagedate = $imagedate;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/     
    public $_pid;
    public $_imageURL;
    public $_thumbURL;
    public $_width;
    public $_height;
    public $_thumbcode;
    public $_description;
    public $_alttext;
    public $_imagedate;
    
    
    public function getTimThumbSrc($width, $height)
    {
        $value = CMS_THEME_URL.'/thumb.php';
        $value .= '?src='.$this->_thumbURL; 
        $value .= '&w='.$width;
        $value .= '&h='.$height;
        $value .= '&z=1'; 
        $value .= '$q=75';
        
        return $value;         
    }
    
    public function getTimThumbSrcRatio($maxwidth, $maxheight)
    {
        $w = $this->_width;
        $h = $this->_height;
        if($w > $maxwidth)
        {
            $ratio = $maxwidth / $this->_width;
            $w = $maxwidth;
            $h = floor($h * $ratio);    
        }

        if($h > $maxheight)
        {
            $ratio = $maxheight / $this->_height;
            $h = $maxheight;
            $w = floor($w * $ratio);                
        }
        
        $value = CMS_THEME_URL.'/thumb.php';
        $value .= '?src='.$this->_imageURL; 
        $value .= '&w='.$w;
        $value .= '&h='.$h;
        $value .= '&z=1'; 
        $value .= '$q=75';
        
        $arr = array();
        $arr['path'] = $value;
        $arr['w'] = $w;
        $arr['h'] = $h;
        return $arr;         
    }    
}

/*********************************************************** 
* Class name:
*    DCC_BaseTools
* Descripton:
*    Implementation of abstract class DCC_BaseTools 
***********************************************************/
class DCC_BasicTools 
{
    public function __construct()
    {
    }    
    
    public function combineArgs($def, $args, $add=false)
    {
        if(!is_array($args)) { $args = array(); }
        
        $combined = $def;
        foreach($def as $key => $value)
        {
            if(array_key_exists($key, $args))
            {
                $combined[$key] = $args[$key];
            }
        }
        
        if($add)
        {
            foreach($args as $key => $value)
            {
                if(!array_key_exists($key, $combined))
                {
                    $combined[$key] = $value;    
                }
            }
        }        
        
        return $combined; 
    }  
    
    public function convertStringTypes($args)
    {
        if(is_array($args))
        {
            foreach($args as $key => $value)
            {
                if($value === 'true') { $args[$key] = true; } 
                else if($value === 'false') { $args[$key] = false; }
            }
        }
        
        return $args;
    }      
    
    public function getImagePreviewBox($args, $echo=false)
    {        
        $text = __('No image', CMS_TXT_DOMAIN);
        
        $def = array(
            'path' => '',
            'display_empty' => true, // display if path is empty            
            'icon' => true, // show zoom icon
            'text' => $text, // information text displayed if path is empty
            'wide' => false,
            'width' => 100,
            'height' => 100,
            'float' => 'none',
            'margin' => '20px 0px 0px 0px',
            'info' => false,
            'info_empty' => false    
        );
        
        $args = $this->combineArgs($def, $args);
        $args['path'] = trim($args['path']);
                
        $out = '';        
                       
        if($args['path'] != '' or ($args['path'] == '' and $args['display_empty']))
        {         
            $style = '';      
            if($args['wide']) { $style .= 'width:100%;box-sizing:border-box;'; } else { $style .= 'width:'.$args['width'].'px;'; } 
            $style .= 'float:'.$args['float'].';margin:'.$args['margin'].';';                   
            $style = ' style="'.$style.'" ';
            
            $out .= '<div class="dc-cms-image-preview-lb-item" '.$style.'>';
                               
                $style = '';
                $style .= 'height:'.$args['height'].'px;line-height:'.$args['height'].'px;';
                if($args['path'] != '') { $style .= 'background-image:url('.$args['path'].');'; }
                $style = ' style="'.$style.'" ';   
   
                $out .= '<div class="image-wrapper" '.$style.'>';
                    if($args['path'] == '')
                    {
                        $out .= $args['text'];
                    } else
                    {
                        if($args['icon'])
                        {
                            $out .= '<span class="look-icon"></span>';
                        }
                    }               
                $out .= '</div>';
                $out .= '<span class="image-path">'.$args['path'].'</span>';
            $out .= '</div>';    
            
            if($args['info'])
            {
                $img_info = dcf_getImageSize($args['path']);
                if(is_array($img_info) or $args['info_empty'])
                {
                    if(!is_array($img_info) and $args['info_empty'])
                    {
                        $img_info['w'] = '-';
                        $img_info['h'] = '-';
                        $img_info['ext'] = '-';    
                    }
                    
                    $out .= '<span class="dc-cms-control-top-label">Image information</span>'; 
                     
                    $out .= '<div class="dc-cms-object-data-box">';
                        $out .= '<div class="option"><div class="property">Width</div><div class="value">'.$img_info['w'].'</div></div>';
                        $out .= '<div class="option"><div class="property">Height</div><div class="value">'.$img_info['h'].'</div></div>';
                        $out .= '<div class="option"><div class="property">Type</div><div class="value">'.strtoupper($img_info['ext']).'</div></div>';                         
                    $out .= '</div>';                        
                }     
            }         
        }
    
        if($echo) { echo $out; } else { return $out; }
    }    
    
    public function attrSelected($value)
    {
        $out = '';
        $out .= $value ? ' selected="selected" ' : ''; 
        return $out;
    }

    public function attrChecked($value)
    {
        $out = '';
        $out .= $value ? ' checked="checked" ' : ''; 
        return $out;
    }        

    public function attrDisabled($value)
    {
        $out = '';
        $out .= $value ? ' disabled="disabled" ' : ''; 
        return $out;
    }        
    
    public function selectCtrlPagesList($args=array(), $echo=false)
    {
        $def = array(
            'value' => CMS_NOT_SELECTED,
            'name' => '',
            'width' => 300,
            'class' => ''
        );
        
        $args = $this->combineArgs($def, $args);
        $out = '';

        $pages_list = GetDCCPI()->getICache()->get_pages();
        
        if(is_array($pages_list))
        {
            $style = '';
            $class = '';
            if($args['width'] != '') { $style = ' style="width:'.$args['width'].'px;" '; }
            if($args['class'] != '') { $class = ' class="'.$args['class'].'" '; }
            
            $out .= '<select '.$style.' name="'.$args['name'].'" '.$class.'><option value="'.CMS_NOT_SELECTED.'">'.__('Not selected', CMS_TXT_DOMAIN).'</option>'; 
            $count = count($pages_list);
            for($i = 0; $i < $count; $i++)
            {
       
                $out .= '<option value="'.$pages_list[$i]->ID.'" ';
                
                if($args['value'] != CMS_NOT_SELECTED)
                {
                    if($pages_list[$i]->ID == $args['value']) { $out .= ' selected="selected" '; }
                }
                
                $out .= '>';
                $out .= $pages_list[$i]->post_title.' (ID:'.$pages_list[$i]->ID.')';
                $out .= '</option>';
                   
            } // for        
            $out .= '</select>';
        }
        
        if($echo) { echo $out; } else { return $out; }     
    }    
    
    public function getGroupFieldBegin($args=array(), $echo=false)
    { 
        $def = array(
            'title' => 'Group title',
            'min_w' => null,
            'max_w' => null,
            'tab' => true,
            'mtop' => null
        );
        
        $args = $this->combineArgs($def, $args);
                                                                                               
        $out = '';
        $style = '';
        if($args['min_w'] != null) { $style .= 'min-width:'.$args['min_w'].'px;'; }
        if($args['max_w'] != null) { $style .= 'max-width:'.$args['max_w'].'px;'; }
        if($args['mtop'] != null) { $style .= 'margin-top:'.$args['mtop'].'px;'; }
        
        if($style != '') { $style = ' style="'.$style.'" '; }
        
        $out .= '<div class="dc-cms-group-field'.($args['tab'] ? '-tab' : '').'" '.$style.'>';                                
            $out .= '<div class="group-title">'.$args['title'].'</div>';        
        
        if($echo) { echo $out; } else { return $out; }   
    }
    
    public function getGroupFieldEnd($echo=false)
    {
        $out = '';
        
            $out .= '<div class="dc-cms-clear"></div>'; 
        $out .= '</div>'; 
        
        if($echo) { echo $out; } else { return $out; }      
    }
    
    public function getEmptySpaceField($height=0, $echo=false)
    {
        $out = '';        
        $out .= '<div class="dc-cms-empty-space-field" style="height:'.$height.'px;"></div>';
        
        if($echo) { echo $out; } else { return $out; }
    }    
    
    public function getCtrlInputInt($name, $value, $min=null, $max=null, $echo=false)
    {
        if($min !== null) { if($value < $min) { $value = $min; } }
        if($max !== null) { if($value > $max) { $value = $max; } }
        
        $out = '';
        $out .= '<div class="dc-cms-control-input-int" >';
            $out .= '<span class="minus"></span>';
            $out .= '<input type="text" name="'.$name.'" value="'.$value.'" />';
            $out .= '<span class="plus"></span>';
            if($max !== null) { $out .= '<span class="dc-cms-hidden max">'.(int)$max.'</span>'; }
            if($min !== null) { $out .= '<span class="dc-cms-hidden min">'.(int)$min.'</span>'; }
        $out .= '</div>'; 
        
        if($echo) { echo $out; } else { return $out; }                           
    }    
    
    public function getCtrlInputIntArgs($args=array(), $echo=false)
    {
        $def = array(
            'name' => '',
            'value' => 0,
            'min' => null,
            'max' => null,
            'disabled' => false,
            'step' => null
        );
        $args = $this->combineArgs($def, $args);
        
        if($args['min'] !== null) { if($args['value'] < $args['min']) { $args['value'] = $args['min']; } }
        if($args['max'] !== null) { if($args['value'] > $args['max']) { $args['value'] = $args['max']; } }
        
        $out = '';
        $out .= '<div class="dc-cms-control-input-int" >';
            $out .= '<span class="minus'.($args['disabled'] ? ' btn-disabled' : '').'"></span>';
            $out .= '<input '.($args['disabled'] ? ' disabled="disabled" ' : '').' type="text" name="'.$args['name'].'" value="'.$args['value'].'" />';
            $out .= '<span class="plus'.($args['disabled'] ? ' btn-disabled' : '').'"></span>';
            if($args['max'] !== null) { $out .= '<span class="dc-cms-hidden max">'.(int)$args['max'].'</span>'; }
            if($args['min'] !== null) { $out .= '<span class="dc-cms-hidden min">'.(int)$args['min'].'</span>'; }
            if($args['step'] !== null) { $out .= '<span class="dc-cms-hidden step">'.(int)$args['step'].'</span>'; }
        $out .= '</div>'; 
        
        if($echo) { echo $out; } else { return $out; }                           
    }      
    
    public function selectCtrlNGGList($args=array(), $echo=false)
    {    
        $def = array(
            'current' => CMS_NOT_SELECTED,
            'name' => '',
            'w' => 300,
            'class' => '',
            'wide' => false
        );
        $args = $this->combineArgs($def, $args);
        
        $out = '';
        
        global $nggdb;
        if(isset($nggdb))
        {
            $gallerylist = $nggdb->find_all_galleries('gid', 'ASC');
            
            $style = '';
                if(!$args['wide']) { $style .= 'width:'.$args['w'].'px;'; }
            $style = ' style="'.$style.'" ';
            
            $class = $args['class'];
            if($args['wide']) { $class .= ' dc-cms-control-wide'; }
            $class = ' class="'.$class.'" ';
            
            $out .= '<select '.$style.' name="'.$args['name'].'" '.$class.'>';
            $out .= '<option value="'.CMS_NOT_SELECTED.'" '.($args['current'] == CMS_NOT_SELECTED ? ' selected="selected" ' : '').' >'.__('Not selected', CMS_TXT_DOMAIN).'</option>';
            foreach($gallerylist as $gal)
            {
                $out .= '<option ';
                $out .= ' value="'.$gal->gid.'" ';
                $out .= $args['current'] == $gal->gid ? ' selected="selected" ' : '';
                $out .= '>'.$gal->title.' (ID: '.$gal->gid.')';
                $out .= '</option>';
            }
            $out .= '</select>';
              
        } else
        {
            $out .= '<span class="dc-cms-exception">'.__('No NextGEN Gallery Plugin Installed or Activated', CMS_TXT_DOMAIN).'</span>';
        }
        
        if($echo) { echo $out; } else { return $out; }           
    }  
    
    public function getBR($count=0, $echo=false)
    {
        $out = '';
        if($count > 0)
        {
            for($i = 0; $i < $count; $i++)
            {
                $out .= '<br />';
            }    
        } else
        {
            $out .= '<br />';
        }
        
        if($echo) { echo $out; } else { return $out; }
    }               
    
    /**
     * Get standard column start HTML code
     * @param args = {float=left, width=300, mright=20, mtop=0, mbottom=0, bg_color=null, padding=0}
     * @param echo = Return or output HTML code
     * @return string HTML code
     */    
    public function getStdColumnStart($args=array(), $echo=false)
    {
        $def = array(
            'float' => 'left',
            'width' => 300,
            'mright' => 20,
            'mtop' => 0,
            'mbottom' => 0,
            'bg_color' => null,
            'padding' => 0
        );    
        
        $args = $this->combineArgs($def, $args);
        
        $style = '';
        $style .= ' style="';
            $style .= 'float:'.$args['float'].';width:'.(int)$args['width'].'px;';
            $style .= 'margin-right:'.(int)$args['mright'].'px;';
            $style .= 'margin-bottom:'.(int)$args['mbottom'].'px;';
            $style .= 'margin-top:'.(int)$args['mtop'].'px;'; 
            $style .= 'padding:'.(int)$args['padding'].'px;';
            if($args['bg_color'] !== null) { $style .= 'background-color:'.$args['bg_color'].';'; }
        $style .= '" ';        
        
        $out = '';
        $out .= '<div class="dc-cms-std-custom-column" '.$style.'>';
        
        if($echo) { echo $out; } else { return $out; }
    }
   
    public function getStdColumnEnd($echo=false)
    {        
        $out = '</div>';    
        if($echo) { echo $out; } else { return $out; }
    }    
    
    public function getNoteStart($args=array(), $echo=false)
    {
        $def = array(
            'type' => 'inline',
            'ptop' => null,
            'pright' => null,
            'pbottom' => null,
            'pleft' => null
        );    
        
        $args = $this->combineArgs($def, $args);        
        
        $out = '';
        
        if($args['type'] == 'inline')
        {
            $out .= '<div class="dc-cms-help-note-inline">';
        } else
        {
            $style = '';
            if($args['ptop'] !== null) { $style .= 'padding-top:'.$args['ptop'].'px;'; }
            if($args['pright'] !== null) { $style .= 'padding-right:'.$args['pright'].'px;'; }
            if($args['pbottom'] !== null) { $style .= 'padding-bottom:'.$args['pbottom'].'px;'; }
            if($args['pleft'] !== null) { $style .= 'padding-left:'.$args['pleft'].'px;'; }
            
            if($style != '') { $style = ' style="'.$style.'" '; }
            
            $out .= '<div class="dc-cms-help-note-box" '.$style.'>';    
        }
        
        if($echo) { echo $out; } else { return $out; } 
    }
    
    public function getNoteEnd($echo=false)
    {        
        $out = '</div>';    
        
        if($echo) { echo $out; } else { return $out; }
    }        
    
    /**
     * Get HTML start code of standard wrapper group of input fields
     * @param args = {mtop=0, mtop-type=null (values:none; small; normal), line-height=22} 
     * @param echo = Return or output HTML code
     * @return string HTML code
     */        
    public function getStdInputsFieldStart($args=array(), $echo=false) 
    {
        $def = array(        
            'mtop' => 0,
            'mtop-type' => null,  // none, small, normal
            'line-height' => 22
        );    
         
        $args = $this->combineArgs($def, $args);
        
        if($args['mtop-type'] !== null)
        {
            switch($args['mtop-type'])
            {
                case 'none': $args['mtop'] = 0; break;
                case 'small': $args['mtop'] = 6; break;
                case 'normal': $args['mtop'] = 15; break;
            }
        }
        
        $style = '';
        $style .= ' style="';
            $style .= 'margin-top:'.(int)$args['mtop'].'px;'; 
            if($args['line-height'] !== null) { $style .= 'line-height:'.(int)$args['line-height'].'px;'; }
        $style .= '" ';   

        $out = '';
        $out .= '<div '.$style.'>'; 
        
        if($echo) { echo $out; } else { return $out; }         
    }
    
    public function getStdInputsFieldEnd($echo=false)
    {        
        $out = '</div>';    
        if($echo) { echo $out; } else { return $out; }
    }
    
    
    public function getBookHelp($args=array(), $echo=false)
    {
        $def = array(
            'text' => ''
        );     
        $args = $this->combineArgs($def, $args);   
        
        $out = '';
        $out .= '<div class="dc-cms-help-note-popup">';
            $out .= '<div>';
                $out .= $args['text'];
            $out .= '</div>';
        $out .= '</div>';
        
        if($echo) { echo $out; } else { return $out; } 
    }
    
    public function getStdWrapperStart($args=array(), $echo=false)
    {
        $def = array(
            'width' => null,
            'min_width' => null,
            'top' => 20,
            'right' => 0,
            'bottom' => 0,
            'left' => 0,
            'bg_color' => null,
            'padding' => null,
            'border' => null
        );    
        
        $args = $this->combineArgs($def, $args);
        
        $style = '';
        $style .= ' style="';
            if($args['width'] !== null) { $style .= 'width:'.(int)$args['width'].'px;'; }
            if($args['min_width'] !== null) { $style .= 'min-width:'.(int)$args['min_width'].'px;'; }
            if($args['border'] !== null) { $style .= 'border:'.$args['border'].';'; }
            if($args['top'] > 0) { $style .= 'margin-top:'.$args['top'].'px;'; }
            if($args['right'] > 0) { $style .= 'margin-right:'.$args['right'].'px;'; }
            if($args['bottom'] > 0) { $style .= 'margin-bottom:'.$args['bottom'].'px;'; }
            if($args['left'] > 0) { $style .= 'margin-left:'.$args['left'].'px;'; }
            if($args['padding'] !== null) { $style .= 'padding:'.$args['padding'].';'; }
            if($args['bg_color'] !== null) { $style .= 'background-color:'.$args['bg_color'].';'; }
        $style .= '" ';        
        
        $out = '';
        $out .= '<div class="dc-cms-std-custom-wrapper" '.$style.'>';
        
        if($echo) { echo $out; } else { return $out; }        
    }    

    public function getStdWrapperEnd($args=array(), $echo=false)
    {
        $out = '</div>';    
        if($echo) { echo $out; } else { return $out; }        
    }
    
    public function getClearBoth($height=null, $echo=false)
    {
        $style = '';
        if($height !== null) { $style = ' style="height:'.(int)$height.'px;" '; }
        $out = '<div class="dc-cms-clear" '.$style.'></div>';    
    
        if($echo) { echo $out; } else { return $out; }
    }
   
    public function getCtrlLabel($args=array(), $echo=false)
    {
        $def = array(
            'label' => '',
            'type' => null
        );    
        
        $args = $this->combineArgs($def, $args);
        
        $out = '';
        switch($args['type'])
        {
            case 'none':
                $out .= '<span class="dc-cms-control-top-label-nomargin">'.$args['label'].'</span>';
            break;

            case 'small':
                $out .= '<span class="dc-cms-control-top-label-s-margin">'.$args['label'].'</span>';
            break;
            
            case 'large':
                $out .= '<span class="dc-cms-control-top-label">'.$args['label'].'</span>';
            break;
            
            default:
                $out .= '<span class="dc-cms-control-top-label">'.$args['label'].'</span>';
            break;                                
        }                                
        
        if($echo) { echo $out; } else { return $out; } 
    }    
    
    public function getStdScrollBoxStart($args=array(), $echo=false)
    {
        $def = array(
            'height' => 100,
            'width' => 'auto'
        );
        
        $args = $this->combineArgs($def, $args);
        
        $out = '';
        $style = '';
        if($args['width'] == 'auto') { $style .= 'width:auto;'; } else { $style .= 'width:'.(int)$args['width'].'px;'; } 
        $style .= 'height:'.(int)$args['height'].'px;';        
        
        $out .= '<div class="dc-cms-std-scroll-box" style="'.$style.'">';
        
        if($echo) { echo $out; } else { return $out; } 
    }
    
    public function getStdScrollBoxEnd($echo=false)
    {
        $out = '</div>';
        
        if($echo) { echo $out; } else { return $out; } 
    }    
    
    public function getMarkedSpan($args=array(), $echo=false)
    {
        $def = array(
            'text' => '',
            'color' => null
        );
        
        $args = $this->combineArgs($def, $args);
        $style = '';
        
        if($args['color'] !== null) { $style .= 'color:'.$args['color'].';'; }
        if($style != '') { $style = ' style="'.$style.'" '; }
        
        $out = '<span class="dc-cms-marked-span" '.$style.'>'.$args['text'].'</span>';
        
        if($echo) { echo $out; } else { return $out; }
        
    }
    
    public function getCMSException($args=array(), $echo=false)
    {
        $def = array(
            'title' => 'CMS Exception',
            'text' => 'Problem description',
            'mtop' => 10
        );    
        
        $args = $this->combineArgs($def, $args);       
        
        $style = ' style="margin-top:'.$args['mtop'].'px;"' ;
        
        $out = '';
        $out .= '<div class="dc-cms-exception" '.$style.'><div class="exception-title">'.$args['title'].'</div>'.$args['text'].'</div>';
       
       if($echo) { echo $out; } else { return $out; } 
    }   
    
    
    public function getTextAreaShortCodeWrapperStart($echo=false)
    {
        $out = '';
        $out .= '<div class="dc-cms-shortcode-textarea-wrapper">';
            $out .= '<img class="dc-cms-add-shortcode-textarea-btn" src="'.CMS_THEME_URL.'/cms/img/lightbulb/shortcodes.png" alt="DC Button" onclick="return false;" />';        
        
       if($echo) { echo $out; } else { return $out; }  
    }
    
    public function getTextAreaShortCodeWrapperEnd($echo=false)
    {
        $out = '';
        $out .= '</div>';
        
       if($echo) { echo $out; } else { return $out; }  
    }   
    
    public function getLegendInlineStart($args=array(), $echo=false)
    {
        $out = '';
        $out .= '<div class="dc-cms-common-legend-inline">';
                
        if($echo) { echo $out; } else { return $out; }
    }  

    public function getLegendInlineItem($args=array(), $echo=false)
    {
        $def = array(
            'url' => '',
            'label' => '',
            'separator' => ',',
            'last' => false,
            'h' => 16
        );
        $args = $this->combineArgs($def, $args);
        
        $out = '';
        
        if($args['url'] != '' and $args['label'] != '')
        {
            $out .= '<div class="item" style="height:'.$args['h'].'px;">';                
                $out .= '<img src="'.$args['url'].'" class="icon" style="height:'.$args['h'].'px;width:'.$args['h'].'px;" />';
                $out .= '<div class="label" style="height:'.$args['h'].'px;line-height:'.$args['h'].'px;">'.$args['label'].($args['last'] ? '' : $args['separator']).'</div>';
            $out .= '</div>';
        }   
                
        if($echo) { echo $out; } else { return $out; }
    }   
    
    public function getLegendInlineEnd($echo=false)
    {
        $out = '';
        
            $out .= '<div class="dc-cms-clear"></div>';
        $out .= '</div>';
                
        if($echo) { echo $out; } else { return $out; }
    }     
    
    public function getFreeSectionHead($args=array(), $echo=false)
    {
        $def = array(
            'label' => 'Default label',
            'top' => 25,
            'bottom' => 25
        );
        $args = $this->combineArgs($def, $args);
                        
        $style = ' style="margin-top:'.$args['top'].'px;margin-bottom:'.$args['bottom'].'px;" ';
        
        $out = '';
        $out .= '<div class="free-section-head" '.$style.'>';
            $out .= $args['label'];
        $out .= '</div>'; 
        
        if($echo) { echo $out; } else { return $out; }   
    }
    
    public function getFreeGrayBoxStart($args=array(), $echo=false)
    {
        $def = array(
            'bgcolor' => '#F4F4F4',
            'padding' => 10,
            'bottom' => 0,
            'top' => 0,
            'bwidth' => 0,
            'bcolor' => '#E0E0E0',
            'bstyle' => 'solid',
            'bt_on' => true,
            'br_on' => true,
            'bb_on' => true,
            'bl_on' => true
        );
        $args = $this->combineArgs($def, $args);
                 
        $style = '';
        $style .= ' style="';
            
            $style .= 'background-color:'.$args['bgcolor'].';';
            $style .= 'padding:'.$args['padding'].'px;';
            if($args['bottom'] > 0) { $style .= 'margin-bottom:'.$args['bottom'].'px;'; }
            if($args['top'] > 0) { $style .= 'margin-top:'.$args['top'].'px;'; }
            if($args['bwidth'] > 0)
            {
                $style .= 'border-width:'.$args['bwidth'].'px;';
                $style .= 'border-color:'.$args['bcolor'].';';
                $style .= 'border-style:'.$args['bstyle'].';';
                
                if(!$args['bt_on']) { $style .= 'border-top:none;'; }
                if(!$args['br_on']) { $style .= 'border-right:none;'; }
                if(!$args['bb_on']) { $style .= 'border-bottom:none;'; }
                if(!$args['bl_on']) { $style .= 'border-left:none;'; }   
            }
            
        $style .= '" ';
        
        $out = '';
        $out .= '<div class="free-gray-box" '.$style.'>';
        
        if($echo) { echo $out; } else { return $out; }   
    }
    
    public function getFreeGrayBoxEnd($echo=false)
    {
        $out = '';
        $out .= '</div>'; 
        
        if($echo) { echo $out; } else { return $out; }   
    }    
        
}

/*********************************************************** 
* Class name:
*    DCC_ControlPanelBase
* Descripton:
*    Implementation of abstract class DCC_ControlPanelBase 
***********************************************************/
class DCC_ControlPanelBase extends DCC_BasicTools
{
    /*********************************************************** 
    * Constructor
    ************************************************************/    
    public function __construct()
    {
    }    

    /*********************************************************** 
    * Public members
    ************************************************************/    

    protected $_submenu = array();
    protected $_process_info = '';
    protected $_process_info_error = '';
    protected $_process_info_exclamation = '';         
    
    /*********************************************************** 
    * Public functions
    ************************************************************/     
    
    public function isMasterPage($name)
    {
        $value = false;
        if(($_GET['page'] == $name and !isset($_GET['subpage'])) or 
           ($_GET['page'] == $name and $_GET['subpage'] == $name)) 
        {
            $value = true;          
        }           
        return $value;  
    }    
    
    public function isSubPage($name)
    {
        $value = false;
        if(isset($_GET['subpage']))
        {
            if($_GET['subpage'] == $name) 
            {
                $value = true;          
            }
        }           
        return $value;  
    }
    
    public function getTopLink()
    {
        $out = '<a name="dc-toplink"></a>';
        return $out;
    }
    
    public function getPanelProcessInfo($echo=false)
    {   
        $gmt_offset = (float)get_option('gmt_offset');          
        $time = time() + $gmt_offset*3600;
        
        $out = '';
        if($this->_process_info != '')
        {                    
            
            $out .= '<span class="dc-cms-process-info"><strong>'.$this->_process_info.'</strong> ('.date('H:i:s', $time).')</span>';            
        } else
        if($this->_process_info_error != '')
        {                    
            $out .= '<span class="dc-cms-process-info-error"><strong>'.$this->_process_info_error.'</strong> ('.date('H:i:s', $time).')</span>';            
        } else 
        if($this->_process_info_exclamation != '')
        {                    
            $out .= '<span class="dc-cms-process-info-exclamation"><strong>'.$this->_process_info_exclamation.'</strong> ('.date('H:i:s', $time).')</span>';            
        }         
        
        if($echo) { echo $out; } else { return $out; }   
    }    
    
    public function getPanelBegin($title='Panel title')
    {
        $out = '';
        $out .= '<div class="dc-cms-single-panel">';
            $out .= '<div class="panel-head"><h3>'.$title.'</h3></div>';
            $out .= '<div class="panel-content">';  
          
        return $out;      
    }
    
    public function getPanelEnd()
    {
        $out = '';
        $out .= '</div></div>';         
        return $out;    
    }
    
    public function getColumnsWraperBegin()
    {
        $out = '<div id="dc-cms-columns-wrapper">';
        return $out;    
    }
    
    public function getColumnsWraperEnd()
    {
        $out = '';
        $out .= '<div class="dc-cms-clear"></div>';
        $out .= '</div>';
        return $out;        
    }

    public function getLeftColumnBegin()
    {
        $out = '<div class="dc-cms-left-column">';
        return $out;    
    }
    
    public function getLeftColumnsEnd()
    {
        $out = '</div>';
        return $out;        
    }
    
    public function getSubmitTopPanel($name, $value="Save changes", $echo=false)
    {
        $out = '';

        $out .= '<div class="dc-cms-submit-panel-top">';
            $out .= '<input class="dc-cms-submit-btn-primary" type="submit" name="'.$name.'" value="'.$value.'"> ';                            
            $out .= $this->getPanelProcessInfo();                            
        $out .= '</div>';          
    
        if($echo) { echo $out; } else { return $out; }    
    }

    public function getSubmitBottomPanel($name, $value="Save changes", $echo=false)
    {
        $out = '';

        $out .= '<div class="dc-cms-submit-panel-bottom">';
            $out .= '<input class="dc-cms-submit-btn-primary" type="submit" name="'.$name.'" value="'.$value.'"> ';
        $out .= '</div>';        
    
        if($echo) { echo $out; } else { return $out; }    
    }    
    
  
    

    
    public function renderNav($global_menu)
    {
        
        $out = '';
        
        $out .= '<div class="dc-cms-menu-column">';
            $out .= '<div class="menu-head "><h3>'.CMS_THEME_NAME.' theme settings</h3></div>';
            $out .= '<ul class="menu">';  
            
                foreach($global_menu as $key => $value)
                {
                    $arrow = '';
                    $class = '';
                    if($_GET['page'] == $value) 
                    { 
                        $arrow = '<div class="arrow"></div>'; 
                        $class = ' class="active-page" ';
                    } else
                    {
                        $arrow = '<div class="arrow-hover"></div>';    
                    }
                                        
                    $out .= '<li '.$class.'>'.$arrow.'<a '.$class.' href="'.admin_url().'admin.php?page='.$value.'">'.$key.'</a>';
                    
                    if($_GET['page'] == $value)
                    {
                        if(isset($this->_submenu))
                        {
                            if(is_array($this->_submenu) and count($this->_submenu))
                            {
                                $out .= '<ul>';
                                    foreach($this->_submenu as $subkey => $subvalue)
                                    {
                                        $class = '';
                                        if((isset($_GET['subpage']) and $_GET['subpage'] == $subvalue and $_GET['page'] == $subvalue) or 
                                           ($_GET['page'] == $subvalue and !isset($_GET['subpage'])) or
                                           (isset($_GET['subpage']) and $_GET['subpage'] == $subvalue))
                                        {
                                            $class = ' class="active-subpage" ';
                                        }
                                        $out .= '<li><a href="'.admin_url().'admin.php?page='.$value.'&subpage='.$subvalue.'" '.$class.'>'.$subkey.'</a></li>';
                                    }
                                $out .= '</ul>';
                            }
                        }
                    }    
                        
                    $out .= '</li>';     
                }
                            
            $out .= '</ul>';      
        $out .= '</div>';  
        
        return $out;                    

    }      
    
    public function selectCtrlWPMenusList($itemvalue, $name, $width)
    {
        $menus = get_terms('nav_menu');
        
        $out = '';
        $out .= '<select style="width:'.$width.'px;" name="'.$name.'"><option value="'.CMS_NOT_SELECTED.'">Not selected</option>';
            
            $count = count($menus);
            for($i = 0; $i < $count; $i++)
            {
       
                $out .= '<option value="'.$menus[$i]->name.'" ';
                
                if($itemvalue !== null)
                {
                    if($menus[$i]->name == $itemvalue) $out .= ' selected="selected" ';
                }
                
                $out .= '>';
                $out .= $menus[$i]->name.' (ID:'.$menus[$i]->term_id.')';
                $out .= '</option>';
                   
            } // for              
        $out .= '</select>';
        return $out;         
    }  
    
     
    
    public function renderPanelSubmenu(& $menu, $head = 'Quick menu:', $echo = true)
    {
        $out = '';
        if(is_array($menu))
        {
             
            $out .= '<div class="cms-sub-menu">'; 
            if($head != '') { $out .= '<div class="head">'.$head.'</div>'; }
            
            foreach($menu as $link => $name)
            {
                $out .= '<a href="#'.$link.'">'.$name.'</a><br />';    
            }
            
            $out .= '</div>';            
        }        
        
        if($echo) { echo $out; } else { return $out; }
    }            

    
    public function getPanelSectionHead($text, $mtop=0)
    {
        $out = '';
        
        $style = '';
        if($mtop != 0) { $style .= 'margin-top:'.$mtop.'px;'; }
        if($style != '') { $style = ' style="'.$style.'" '; }
        
        $out .= '<div class="section-head" '.$style.'>'.$text;
        $out .= '</div>';        
        
        return $out;  
    }
    
    /**
     * CMS panel section small head
     * @param text string to display as head title
     * @param mtop top margin, default set to zero
     * 
     * @return string HTML code
     */      
    public function getPanelSectionHeadSmall($text, $mtop=0)
    {
        $out = '';
        
        $style = '';
        if($mtop != 0) { $style .= 'margin-top:'.$mtop.'px;'; }
        if($style != '') { $style = ' style="'.$style.'" '; }
        
        $out .= '<div class="section-head-small" '.$style.'>'.$text;
        $out .= '</div>';        
        
        return $out;  
    }    
    

}

/*********************************************************** 
* Class name:
*    DCC_ContactForm
* Descripton:
*    - 
***********************************************************/
class DCC_ContactForm extends DCC_BasicTools  
{
    public function __construct($args=array())
    {
        $def = array(
            'id' => time(),
            'name' => 'Default contact form name',
            'inputs' => array()
        );        
        $args = $this->combineArgs($def, $args);        
        
        $this->_id = $args['id']; 
        $this->_name = $args['name'];
        $this->_inputs = $arga['inputs'];
    } 
    
    public $_id;
    public $_name;   
    public $_inputs;       
}

/*********************************************************** 
* Class name:
*    DCC_ContactFormInput
* Descripton:
*    - 
***********************************************************/
class DCC_ContactFormInput extends DCC_BasicTools
{
    public function __construct($args=array())
    {
        $def = array(
            'type' => 'text',
            'label' => 'Control label',
            'required' => false,
            'default' => '',
            'default_option' => CMS_NOT_SELECTED, 
            'options' => array(),
            'is_email' => false,
            'is_authorization' => false,
            'hide' => false,
            'hide_label' => false,
            'use_default' => false,
            'width' => 270,
            'height' => 180,
            'use_width' => false,
            'use_height' => false,
            'func_name' => false,
            'func_email' => false,
            'func_message' => false,
            'func_subject' => false,
            'func_info' => false
        );        
        $args = $this->combineArgs($def, $args);
        
        $this->_type = $args['type'];
        $this->_label = $args['label'];
        $this->_required = $args['required'];
        $this->_default = $args['default'];
        $this->_default_option = $args['default_option'];
        $this->_options = $args['options'];
        $this->_is_email = $args['is_email'];
        $this->_is_authorization = $args['is_authorization']; 
        $this->_hide = $args['hide'];
        $this->_hide_label = $args['hide_label'];
        $this->_use_default = $args['use_default'];  
        $this->_width = $args['width'];
        $this->_height = $args['height'];
        $this->_use_width = $args['use_width'];
        $this->_use_height = $args['use_height'];
        $this->_func_name = $args['func_name'];
        $this->_func_email = $args['func_email'];
        $this->_func_message = $args['func_message']; 
        $this->_func_subject = $args['func_subject']; 
        $this->_func_info = $args['func_info'];          
    } 
    
    public $_type; // text, select, textarea
    public $_label;
    public $_required;
    public $_default;
    public $_default_option;
    public $_options;
    public $_is_email;
    public $_is_authorization;
    public $_hide;  
    public $_hide_label;
    public $_use_default;
    public $_width;
    public $_height;
    public $_use_width;
    public $_use_height; 
    public $_func_name;
    public $_func_email;
    public $_func_message;
    public $_func_subject;
    public $_func_info;            
}

/*********************************************************** 
* Class name:
*    DCC_ContactFormSelectOption
* Descripton:
*    - 
***********************************************************/
class DCC_ContactFormSelectOption extends DCC_BasicTools
{
    public function __construct($args=array())
    {
        $def = array(
            'id' => time(),
            'value' => 'Option value'
        );        
        $args = $this->combineArgs($def, $args);
        
        $this->_id = $args['id'];
        $this->_value = $args['value'];        
    }     

    public $_id;      
    public $_value;
}

/*********************************************************** 
* Class name:
*    DCC_Rectangle
* Descripton:
***********************************************************/
 class DCC_Rectangle
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($w=0, $h=0)
    {
        $this->_width = $w;
        $this->_height = $h;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/     
    public $_width;
    public $_height;      
}


/*********************************************************** 
* Class name:
*    DCC_CommonLink
* Descripton:
***********************************************************/
class DCC_CommonLink
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct()
    {
        $this->_link = '';
        $this->_page = CMS_NOT_SELECTED;
        $this->_type = 'page'; // page, user
        $this->_target = '_self';
        $this->_text = 'Link Name'; // _self, _blank
        $this->_use = false;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/     
    public $_link;
    public $_page;
    public $_type;
    public $_target;
    public $_text;
    public $_use;        
}

/*********************************************************** 
* Class name:
*    DCC_PositionedImage
* Descripton:
***********************************************************/
 class DCC_PositionedImage extends DCC_BasicTools
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($args)
    {
        $def = array(
            'width' => 100, 
            'height' => 100, 
            'left' => 0, 
            'top' => 0, 
            'right' => 0, 
            'bottom' => 0, 
            'imgurl' => '', 
            'url' => '',
            'target' => '_self'
        );
        
        $args = $this->combineArgs($def, $args);
        
        $this->_width = $args['width'];
        $this->_height = $args['height'];
        $this->_left = $args['left'];
        $this->_top = $args['top'];
        $this->_right = $args['right'];
        $this->_bottom = $args['bottom'];
        $this->_imgurl = $args['imgurl'];
        $this->_url = $args['url'];
        $this->_target = $args['target'];
        
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/     
    public $_width;
    public $_hight;
    public $_left;
    public $_top;
    public $_right;
    public $_bottom;
    public $_imgurl;
    public $_url;
    public $_target;        
    

} 

/*********************************************************** 
* Class name:
*    DCC_CGoogleFont
* Descripton:
***********************************************************/
class DCC_GoogleFont
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($name, $css, $url)
    {
        $this->_name = $name;
        $this->_css = $css;
        $this->_url = $url;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/ 
    public $_name;    
    public $_css;
    public $_url;     
}

/*********************************************************** 
* Class name:
*    DCC_GoogleFontManager
* Descripton:
***********************************************************/
class DCC_GoogleFontManager 
{
    public function __construct()
    {
        $this->_DBIDOPT_FONT_TABLE = CMS_THEME_NAME_UPPERCASE.'_GFONT_LIST_OPT';
        
        $this->_fontlist = get_option($this->_DBIDOPT_FONT_TABLE);
        if(!is_array($this->_fontlist))
        {
            $this->_fontlist = array();
            $this->restoreDefaultFonts();            
        }        
    } 

    private $_DBIDOPT_FONT_TABLE = null;
    private $_fontlist = array();
    
    public function getFontList()
    {
        return $this->_fontlist;
    }

    public function getFontsCount()
    {
        return count($this->_fontlist);
    }    
    
    public function deleteFont($index)
    {
       if(is_array($this->_fontlist))
       {
           unset($this->_fontlist[$index]);
           $this->_fontlist = array_values($this->_fontlist);
           update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);     
       } 
    }   
    
    public function deleteFontList($indexes_list=array())
    {
       if(is_array($this->_fontlist) and is_array($indexes_list))
       {
           foreach($indexes_list as $index)
           {
                unset($this->_fontlist[$index]);
           }
           $this->_fontlist = array_values($this->_fontlist);
           update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);     
       } 
    }      
    
    public function addFont($name, $css, $url)
    {
       $result = $this->addGoogleFont($name, $css, $url); 
       if($result)
       {               
            update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);     
       }
       return $result;
    }       
    
    public function restoreDefaultFonts()
    {
        $this->_fontlist = array();
        $this->setDefaultFonts();
        update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);    
    }
    
    public function findFontByURL($url)
    {
        $result = null;
        if(is_array($this->_fontlist))
        {
            foreach($this->_fontlist as $font)
            {
                if($font->_url == $url)
                {
                    $result = $font;
                    break;
                }
            }    
        }    
        return $result;    
    }
    
    public function selectFontList($selected, $name, $width=300)
    {
        $out = '';
        
        if(is_array($this->_fontlist))
        {                
            $out .= '<select name="'.$name.'" style="width:'.$width.'px;">';
                foreach($this->_fontlist as $font)
                {
                    $out .= '<option value="'.$font->_url.'" ';
                    if($selected == $font->_url) 
                    {
                        $out .= ' selected="selected" ';
                    }
                    $out .= '>'.$font->_name.'</option>';
                }    
            $out .= '</select>';
        }
        return $out;
    }       
    
    private function setDefaultFonts()
    {
        // A
        $this->addGoogleFont('Aclonica', "'Aclonica', arial, serif", 'http://fonts.googleapis.com/css?family=Aclonica'); 
        $this->addGoogleFont('Allan', "'Allan', arial, serif", 'http://fonts.googleapis.com/css?family=Allan:bold');
        $this->addGoogleFont('Allerta', "'Allerta', arial, serif", 'http://fonts.googleapis.com/css?family=Allerta'); 
        $this->addGoogleFont('Amaranth', "'Amaranth', arial, serif", 'http://fonts.googleapis.com/css?family=Amaranth'); 
        $this->addGoogleFont('Annie Use Your Telescope', "'Annie Use Your Telescope', arial, serif", 'http://fonts.googleapis.com/css?family=Annie+Use+Your+Telescope');
        $this->addGoogleFont('Anton', "'Anton', arial, serif", 'http://fonts.googleapis.com/css?family=Anton');
        $this->addGoogleFont('Architects Daughter', "'Architects Daughter', arial, serif", 'http://fonts.googleapis.com/css?family=Architects+Daughter');       
        // B
        $this->addGoogleFont('Bangers', "'Bangers', arial, serif", 'http://fonts.googleapis.com/css?family=Bangers'); 
        // C
        $this->addGoogleFont('Cabin', "'Cabin', arial, serif", 'http://fonts.googleapis.com/css?family=Cabin'); 
        $this->addGoogleFont('Cabin Sketch', "'Cabin Sketch', arial, serif", 'http://fonts.googleapis.com/css?family=Cabin+Sketch:bold'); 
        $this->addGoogleFont('Calligraffitti', "'Calligraffitti', arial, serif", 'http://fonts.googleapis.com/css?family=Calligraffitti');
        $this->addGoogleFont('Carter One', "'Carter One', arial, serif", 'http://fonts.googleapis.com/css?family=Carter+One'); 
        $this->addGoogleFont('Chewy', "'Chewy', arial, serif", 'http://fonts.googleapis.com/css?family=Chewy'); 
        $this->addGoogleFont('Copse', "'Copse', arial, serif", 'http://fonts.googleapis.com/css?family=Copse'); 
        $this->addGoogleFont('Corben', "'Corben', arial, serif", 'http://fonts.googleapis.com/css?family=Corben:bold');
        $this->addGoogleFont('Crafty Girls', "'Crafty Girls', arial, serif", 'http://fonts.googleapis.com/css?family=Crafty+Girls'); 
        $this->addGoogleFont('Crushed', "'Crushed', arial, serif", 'http://fonts.googleapis.com/css?family=Crushed');
        $this->addGoogleFont('Cuprum', "'Cuprum', arial, serif", 'http://fonts.googleapis.com/css?family=Cuprum');  
        // Y
        $this->addGoogleFont('Yanone Kaffeesatz', "'Yanone Kaffeesatz', sans-serif", 'http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz');  
                   
    }             
    
    private function addGoogleFont($name, $css, $url)
    {
        $result = false;
        if(!$this->isFontOnList($name, $css, $url))
        {
            $font = new DCC_GoogleFont($name, $css, $url);
            array_push($this->_fontlist, $font);
            $result = true;          
        }    
        
        return $result;
    }   
    
    
    
    private function isFontOnList($name, $css, $url)
    {
        $result = false;
        if(is_array($this->_fontlist))
        {
            foreach($this->_fontlist as $font)
            {
                if($font->_url == $url)
                {
                    $result = true;
                    break;
                }    
            }
        }
        return $result;    
    } 
}

/*********************************************************** 
* Class name:
*    DCC_CufonFont
* Descripton:
***********************************************************/
class DCC_CufonFont
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($name, $file)
    {
        $this->_name = $name;
        $this->_file = $file;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/ 
    public $_name;    
    public $_file;   
}

/*********************************************************** 
* Class name:
*    DCC_CufonFontManager
* Descripton:
***********************************************************/
class DCC_CufonFontManager 
{
    public function __construct($catalog_name='fonts')
    {
        $this->_DBIDOPT_FONT_TABLE = CMS_THEME_NAME_UPPERCASE.'_FONT_LIST_OPT';
        $this->_catalog_name = $catalog_name;
        
        $this->_fontlist = get_option($this->_DBIDOPT_FONT_TABLE);
        if (!is_array($this->_fontlist))
        {
            $this->updateFonts();
        }        
    } 
    
    private $_DBIDOPT_FONT_TABLE = null;
    private $_fontlist = array();
    private $_catalog_name = '';   
    
    
    public function selectFontList($selected, $name, $width=300)
    {
        $out = '';
        
        if(is_array($this->_fontlist))
        {                
            $out .= '<select name="'.$name.'" style="width:'.$width.'px;">';
                foreach($this->_fontlist as $font)
                {
                    $out .= '<option value="'.$font->_file.'" ';
                    if($selected == $font->_file) 
                    {
                        $out .= ' selected="selected" ';
                    }
                    $out .= '>'.$font->_name.'</option>';
                }    
            $out .= '</select>';
        }
        return $out;
    }   
    
    public function updateFonts()
    {
        $newlist = $this->loadFonts();
        $this->_fontlist = $newlist;
                
        update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);     
    }
    
    public function loadFonts()
    {
        $path = CMS_TEMPLATEPATH.'/'.$this->_catalog_name; 
        $newlist = array();
        
        $is_dir = is_dir($path);
        if($is_dir)
        {
            $dh = null;
            if($dh = opendir($path)) 
            {
                $file = null;
                while(($file = readdir($dh)) !== false) 
                {
                    if($file != '.' and $file != '..')
                    {
                        if(!is_dir($file))
                        {
                            $info = pathinfo($file);
                            if(strtolower($info['extension']) == 'js')
                            {
                                $font = new DCC_CufonFont($file, $file);
                                array_push($newlist, $font);
                            }
                        }
                    }
                }
                closedir($dh);
            }
        }   
        
        return $newlist;
    } 
}





/*********************************************************** 
* Class name:
*    DCC_FontFaceFont
* Descripton:
***********************************************************/
class DCC_FontFaceFont
{    
    /*********************************************************** 
    * Constructor
    ************************************************************/     
    public function __construct($name, $file)
    {
        $this->_name = $name;
        $this->_file = $file;
    }
   
    /*********************************************************** 
    * Public members
    ************************************************************/ 
    public $_name;    
    public $_file;   
}

/*********************************************************** 
* Class name:
*    DCC_FontFaceManager
* Descripton:
***********************************************************/
class DCC_FontFaceManager 
{
    public function __construct($catalog_name='fonts')
    {
        $this->_DBIDOPT_FONT_TABLE = CMS_THEME_NAME_UPPERCASE.'_FF_FONT_LIST_OPT'; 
        $this->_catalog_name = $catalog_name;
        
        $this->_fontlist = get_option($this->_DBIDOPT_FONT_TABLE);
        if(!is_array($this->_fontlist))
        {
            $this->updateFonts();
        }       
        
    
    } 

    private $_DBIDOPT_FONT_TABLE = null;
    private $_fontlist = array();  
    private $_catalog_name = '';  

    public function getFontByFileName($file)
    {
        $result = null;
        
        if(is_array($this->_fontlist))
        {
            foreach($this->_fontlist as $font)
            {
                if($font->_file == $file)
                {
                    $result = $font;
                    break;
                }
            }
        }
        
        return $result;
    }
    
    public function selectFontList($selected, $name, $width=300)
    {
        $out = '';
        
        if(is_array($this->_fontlist))
        {                
            $out .= '<select name="'.$name.'" style="width:'.$width.'px;">';
                foreach($this->_fontlist as $font)
                {
                    $out .= '<option value="'.$font->_file.'" ';
                    if($selected == $font->_file) 
                    {
                        $out .= ' selected="selected" ';
                    }
                    $out .= '>'.$font->_name.'</option>';
                }    
            $out .= '</select>';
        }
        return $out;
    }   
    
    public function updateFonts()
    {
        $newlist = $this->loadFonts();
        $this->_fontlist = $newlist;
                
        update_option($this->_DBIDOPT_FONT_TABLE, $this->_fontlist);     
    }
    
    public function loadFonts()
    {
        $path = CMS_TEMPLATEPATH.'/'.$this->_catalog_name; 
        $newlist = array();
        
        $is_dir = is_dir($path);
        if($is_dir)
        {
            $dh = null;
            if($dh = opendir($path)) 
            {
                $file = null;
                while(($file = readdir($dh)) !== false) 
                {
                    if($file != '.' and $file != '..')
                    {
                        if(!is_dir($file))
                        {
                            $info = pathinfo($file);
                            if(strtolower($info['extension']) == 'woff')
                            {
                                $font = new DCC_CufonFont($file, $file);
                                array_push($newlist, $font);
                            }
                        }
                    }
                }
                closedir($dh);
            }
        }   
        
        return $newlist;
    }        
    
}

/*********************************************************** 
* Class name:
*    DCC_ServerCatalogContent
* Descripton:
***********************************************************/   
class DCC_ServerCatalogContent extends DCC_BasicTools 
{
    public function __construct()
    {        
    }
    
    public $_files_list = array();  
    
    public function readCatalog($args=array())
    {
        $def = array(
            'catalog' => '',
            'tolower' => false
        );
        $args = $this->combineArgs($def, $args);

        
        $path = CMS_TEMPLATEPATH.'/'.$args['catalog']; 
        $newlist = array();    

        $is_dir = is_dir($path);
        if($is_dir)
        {
            $dh = null;
            if($dh = opendir($path)) 
            {
                $file = null;
                while(($file = readdir($dh)) !== false) 
                {
                    if($file != '.' and $file != '..')
                    {
                        if(!is_dir($file))
                        {
                            $info = pathinfo($file);
                            $basename = $info['basename'];
                            if($args['tolower']) { $basename = strtolower($basename); }
                            array_push($newlist, $basename);
                        }
                    }
                }
                closedir($dh);
            }            
        }
        
        $this->_files_list = $newlist;
        return $newlist;            
    }    
    
    
    public function fileExist($args=array())
    {
        $def = array(
            'name' => '',
            'ext' => ''
        );
        $args = $this->combineArgs($def, $args);
        $args['name'] = strtolower($args['name']);
        $args['ext'] = strtolower($args['ext']);        
        
        $result = false;
        
        if($args['name'] != '' and $args['ext'] == '')
        {        
            if(is_array($this->_files_list))
            {
                foreach($this->_files_list as $file)
                {
                    if($args['name'] == strtolower($file))
                    {
                        $result = true;
                        break;
                    }   
                }    
            }        
        } else
        if($args['name'] != '' and $args['ext'] != '')
        {
            if(is_array($this->_files_list))
            {
                foreach($this->_files_list as $file)
                {
                    $split = explode('.', $file);
                    $name = strtolower($split[0]);
                    $ext = strtolower($split[1]);
                    
                    if($args['name'] == $name and $args['ext'] == $ext)
                    {
                        $result = true;
                        break;
                    }   
                }    
            }            
        }

        return $result;
    }  
}

/*********************************************************** 
* Class name:
*    DCC_HeaderInfoBoxEntry
* Descripton:
***********************************************************/   
class DCC_HeaderInfoBoxEntry extends DCC_BasicTools
{
    public function __construct($args=array())
    {
        $def = array(
            'text' => '',
            'hide' => false
        );    
        
        $args = $this->combineArgs($def, $args);
        
        $this->_text = $args['text'];
        $this->_hide = $args['hide'];
    }
    
    public $_text;
    public $_hide;
}   
   
   
/*********************************************************** 
* Class name:
*    DCC_WPPost
* Descripton:
***********************************************************/   

class DCC_WPPost 
{
    public function __construct($post=null)
    {                
        if($post !== null)
        {
            $this->ID = $post->ID;
            $this->post_author = $post->post_author; 
            $this->post_date = $post->post_date;
            $this->post_date_gmt = $post->post_date_gmt;
            
            $this->post_content = $post->post_content;
            $this->post_title = $post->post_title;
            $this->post_excerpt = $post->post_excerpt;
            $this->post_status = $post->post_status;
            
            $this->comment_status = $post->comment_status;
            $this->ping_status = $post->ping_status;
            $this->post_password = $post->post_password;
            $this->post_name = $post->post_name;
            
            $this->to_ping = $post->to_ping;
            $this->pinged = $post->pinged;
            $this->post_modified = $post->post_modified;
            $this->post_modified_gmt = $post->post_modified_gmt;
            
            $this->post_content_filtered = $post->post_content_filtered;
            $this->post_parent = $post->post_parent;
            $this->guid = $post->guid;
            $this->menu_order = $post->menu_order;
            
            $this->post_type = $post->post_type;
            $this->post_mime_type = $post->post_mime_type;
            $this->comment_count = $post->comment_count;
            $this->filter = $post->filter;     
        }                    
    } 
    
    public $ID;
    public $post_author;
    public $post_date;
    public $post_date_gmt;
    
    public $post_content;
    public $post_title;
    public $post_excerpt;
    public $post_status;
    
    public $comment_status;
    public $ping_status;
    public $post_password;
    public $post_name;
    
    public $to_ping;
    public $pinged;
    public $post_modified;
    public $post_modified_gmt;
    
    public $post_content_filtered;
    public $post_parent;
    public $guid;
    public $menu_order;
    
    public $post_type;
    public $post_mime_type;
    public $comment_count;
    public $filter;        
} 
 
    
/**
 * Image resizing class
 * 
 * @author freshface
 * @version 1.2
 * @link http://www.freshface.net
 * @link http://github.com/boobslover/freshizer
 * @license GNU version 2
 */

class DCC_FreShizer 
{ 
    const IMAGE_CROP_FIT = 1;
    const IMAGE_NOCROP = 2; 
    const IMAGE_NOCROP_FIT = 3;
    
    const IMAGE_FILTER_NONE = 1;
    const IMAGE_FILTER_GRAYSCALE = 2;
    
    private static function customUserSettings() 
    {
        // caching interval -> basically tells when the image is expiring
        self::$caching_interval = 86400; // [seconds] = 24 hr
        // enable / disable caching
        self::$enable_caching = true;     // is caching enabled ?
        // If you leave null, it will automatically use freshizer directory in wp-content/uploads
        // but if you dont want to use this plugin with wordpress, just specify the directory path here
        //self::$upload_dir['basedir'] = /yourserver/documentroot/domain/data/image_store;
        //self::$upload_dir['baseurl'] = http://www.domain.com/data/image_store;
        self::$upload_dir = null;
        
    }

    protected static $caching_interval = 86400;             // [seconds] 86400 sec = 24hr
    protected static $enable_caching = true;                // allow caching            
    protected static $upload_dir = null;                    // upload directory, here we store all resized images      
    private static $echo_error = false;
      
    /**
     * Initialization of all functions for proper work of this class
     */
    public static function init() 
    {
        self::customUserSettings();                            // load custom user settings
        self::getUploadDir();                                // load upload directory ( WP or script url )
        self::createDir();                                    // create that directory
    }     
    
    /**
     * Get upload dir, if has been not defined. If we are in wordpress, then use the wp-content directory. If not, use script path and url
     */
    private static function getUploadDir() 
    {
        if(self::$upload_dir == null && function_exists('wp_upload_dir')) 
        {
            self::$upload_dir = wp_upload_dir();
            self::$upload_dir['basedir'] .= '/freshizer';
            self::$upload_dir['baseurl'] .='/freshizer';        
        } else 
        if(self::$upload_dir == null && !function_exists('wp_upload_dir')) 
        {
            $script_dir = realpath(dirname(__FILE__));
            $script_url = 'http://'.$_SERVER['SERVER_NAME'] . str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', $script_dir);
            self::$upload_dir['basedir'] = $script_dir.'/freshizer';
            self::$upload_dir['baseurl'] = $script_url.'/freshizer';
        }    
    }
    
    /**
     * Resize image and save it to the upload directory
     * @param string url Link to the source image
     * @param int width Wanted width
     * @param int height Wanted height
     * @param int crop Do we want crop ( fixed height )
     * 
     * @return string Resized Image url
     */
    public static function resize( $url, $width, $height = false, $mode = self::IMAGE_CROP_FIT, $filter = self::IMAGE_FILTER_NONE) 
    {
        $img_old_relative_path = self::getRelativePath( $url );            // here we get relative path to better resizing 

        $img_old_size = self::getImageSize( $img_old_relative_path );    // get image size returned in array
        
        if( $img_old_size == false ) {
            if(self::$echo_error) { echo 'Image does not exists'; }
            return false;
        }
                                     
        $dim = self::calculateNewDimensions($img_old_size['width'], $img_old_size['height'], $width, $height, $mode);        // calculate new dimensions
        $img_new_hash = self::getImgHash( $img_old_relative_path, $img_old_size, $mode, $filter);                                            // get image hash for unique identification
        $img_new_path = self::getNewImagePath($img_old_relative_path, $img_new_hash, $dim['img']['w'], $dim['img']['h']);    // create new img path ( in upload dir)
        $img_new_url =  self::getNewImageUrl($img_old_relative_path, $img_new_hash, $dim['img']['w'], $dim['img']['h']);    // create new img url
        
        // if the image does not exists ( == it's not cached ) then create it
        if(!file_exists($img_new_path)) 
        {
            self::resizeImage($img_old_relative_path, $img_new_path, $dim, $filter);
        }
        return $img_new_url;
    }
    
    /** 
     * Image resizing, the core. This function load the original image, resize it and save as a new iamge
     * @param string $img_old_path Path to the old image
     * @param string $img_new_path Path to the new image
     * @param array  $dimensions   Dimensions of the old and new images
     */
    protected static function resizeImage($img_old_path, $img_new_path, $dimensions, $filter) 
    {
        // load image and in case of failure echo error and return
        $img_old = self::loadImage($img_old_path);            
        if(!is_resource($img_old)) 
        {
            if(self::$echo_error) { echo 'Error loading image'; }
            return false;
        }
        
        $img_new = self::createImage($dimensions['img']['w'], $dimensions['img']['h']);    // create new true color image
        
        // copy original image to new one
        imagecopyresampled($img_new, $img_old, $dimensions['dst']['x'], $dimensions['dst']['y'], $dimensions['src']['x'], $dimensions['src']['y'], $dimensions['dst']['w'], $dimensions['dst']['h'], $dimensions['src']['w'], $dimensions['src']['h']);
        
        if($filter == self::IMAGE_FILTER_GRAYSCALE and function_exists('imagefilter'))
        {
            imagefilter($img_new, IMG_FILTER_GRAYSCALE);
        }
        
        // save the image
        self::saveImage($img_new, $img_new_path);
        // destroi the images
        imagedestroy($img_new);
        imagedestroy($img_old);
        
    }

    /**
     * Taken Over from Wordpress Core. This function calculates the best dimension, if we want to crop or not.
     */
    protected static function calculateNewDimensions($orig_w, $orig_h, $area_w, $area_h, $mode = self::IMAGE_CROP_FIT) 
    {         
        if(self::IMAGE_NOCROP_FIT == $mode) 
        {
            $img_w = $area_w;
            $img_h = $area_h;
            
            $s_x = 0;
            $s_y = 0;                       
            $src_w = $orig_w;
            $src_h = $orig_h;            
                        
            if($orig_w > $area_w)
            {
                $ratio = $area_w / $orig_w;
                $orig_w = $area_w;
                $orig_h = floor($ratio * $orig_h);     
            }

            if($orig_h > $area_h)
            {
                $ratio = $area_h / $orig_h;
                $orig_h = $area_h;
                $orig_w = floor($ratio * $orig_w);     
            }
            
            $dst_x = floor($area_w / 2) - floor($orig_w / 2);
            $dst_y = floor($area_h / 2) - floor($orig_h / 2);
            
            $dst_w = $orig_w;
            $dst_h = $orig_h;
                            
        } else
        if(self::IMAGE_CROP_FIT == $mode) 
        {            
            // crop the largest possible portion of the original image that we can size to $area_w x $area_h
            $aspect_ratio = $orig_w / $orig_h;
            $dst_w = $area_w;// min($area_w, $orig_w);
            $dst_h = $area_h;// min($area_h, $orig_h);
    
            if(!$dst_w) 
            {
                $dst_w = intval($dst_h * $aspect_ratio);
            }
    
            if(!$dst_h) 
            {
                $dst_h = intval($dst_w / $aspect_ratio);
            }
    
            $size_ratio = max($dst_w / $orig_w, $dst_h / $orig_h);
    
            $src_w = round($dst_w / $size_ratio);
            $src_h = round($dst_h / $size_ratio);
    
            $s_x = floor( ($orig_w - $src_w) / 2 );
            $s_y = floor( ($orig_h - $src_h) / 2 ); 
            
            $dst_x = 0;
            $dst_y = 0;            
            $img_w = $dst_w;
            $img_h = $dst_h;
        } else 
        if(self::IMAGE_NOCROP == $mode)
        {
            // don't crop, just resize using $area_w x $area_h as a maximum bounding box
            $src_w = $orig_w;
            $src_h = $orig_h;
    
            $s_x = 0;
            $s_y = 0;    
        
            list( $dst_w, $dst_h ) = self::constrainNewDimensions( $orig_w, $orig_h, $area_w, $area_h );
            
            $dst_x = 0;
            $dst_y = 0;            
            $img_w = $dst_w;
            $img_h = $dst_h;
        }
        
        $to_return = array();                        
        $to_return['img']['w'] = (int)$img_w;
        $to_return['img']['h'] = (int)$img_h;        

        $to_return['src']['x'] = (int)$s_x;
        $to_return['src']['y'] = (int)$s_y;
        $to_return['src']['w'] = (int)$src_w;
        $to_return['src']['h'] = (int)$src_h;
        
        $to_return['dst']['x'] = (int)$dst_x;
        $to_return['dst']['y'] = (int)$dst_y;
        $to_return['dst']['w'] = (int)$dst_w;
        $to_return['dst']['h'] = (int)$dst_h;        
                  
        return $to_return;
    }

    /**
     * This function has been take over from wordpress core. It calculate the best proportion to uncropped image
     */
    protected static function constrainNewDimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) 
    {
        
        if ( !$max_width and !$max_height )
            return array( $current_width, $current_height );
    
        $width_ratio = $height_ratio = 1.0;
        $did_width = $did_height = false;
    
        if ( $max_width > 0 && $current_width > 0 ) 
        {
            $width_ratio = $max_width / $current_width;
            $did_width = true;
        }
    
        if ( $max_height > 0 && $current_height > 0 ) 
        {
            $height_ratio = $max_height / $current_height;
            $did_height = true;
        }
    
        // Calculate the larger/smaller ratios
        $smaller_ratio = min( $width_ratio, $height_ratio );
        $larger_ratio  = max( $width_ratio, $height_ratio );
    
        if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
             // The larger ratio is too big. It would result in an overflow.
            $ratio = $smaller_ratio;
        else
            // The larger ratio fits, and is likely to be a more "snug" fit.
            $ratio = $larger_ratio;
    
        $w = intval( $current_width  * $ratio );
        $h = intval( $current_height * $ratio );
    
        // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
        // We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
        // Thus we look for dimensions that are one pixel shy of the max value and bump them up
        if ( $did_width && $w == $max_width - 1 )
            $w = $max_width; // Round it up
        if ( $did_height && $h == $max_height - 1 )
            $h = $max_height; // Round it up
    
        return array( $w, $h );
    }

    /**
     * Get Image size, if the image does not exists, return false
     * 
     * @param string Relative path to the image
     * @return bool / string When fail false, other image dimensions
     */
    protected static function getImageSize($relative_image_path) 
    {
        // does the file exists ? If no, return false
        if(!file_exists($relative_image_path)) 
        {
            return false;
        }
        
        // get image sizes
        $image_size = getimagesize($relative_image_path);
        $image['path'] = $relative_image_path;
        $image['width'] = $image_size[0];
        $image['height'] = $image_size[1];
        
        return $image;
    }    
     
    /**
     * Decide which image type it is and load it -> TAKEN OVER FROM WORDPRESS
     * 
     * @param string path Path to the image
     * @return resource Image Resource ID
     */
    protected static function loadImage($file) 
    {
           if ( is_numeric( $file ) )
                $file = get_attached_file( $file );
        
            if ( ! file_exists( $file ) )
                return false;
        
            if ( ! function_exists('imagecreatefromstring') )
                return false;
        
            // Set artificially high because GD uses uncompressed images in memory
            @ini_set( 'memory_limit', '256M' );
            $image = imagecreatefromstring( file_get_contents( $file ) );
        
            if ( !is_resource( $image ) )
                return false;
        
            return $image;        
    }    
    /**
     * Create image truecolor -> TAKEN OVER FROM WORDPRESS
     */
    protected static function createImage ($width, $height) 
    {
        $img = imagecreatetruecolor($width, $height);

        if(is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha')) 
        {
            $canvas_color = 'FFFFFF';
            
            $canvas_color_R = hexdec (substr ($canvas_color, 0, 2));
            $canvas_color_G = hexdec (substr ($canvas_color, 2, 2));
            $canvas_color_B = hexdec (substr ($canvas_color, 4, 2));        
            
            $color = imagecolorallocatealpha ($img, $canvas_color_R, $canvas_color_G, $canvas_color_B, 0);
            imagefill ($img, 0, 0, $color);              
            
            imagealphablending($img, false);
            imagesavealpha($img, true);
        }
        return $img;
    }
    
    /**
     * Decide which image type it is and save it
     * 
     * @param resource $image Image resource
     * @param string $path Path to the image
     */
    protected static function saveImage( $image, $path ) 
    {
        $pinfo = pathinfo( $path );
        $ext = $pinfo['extension'];
        $return = null;
        
        switch( $ext ) {
            case 'jpg':
                $return = imagejpeg($image, $path, 100);
                break;
            case 'jpeg':
                $return = imagejpeg($image, $path, 100);
                break;    
            case 'png':
                $return = imagepng( $image, $path, 4);
                break;
            
            case 'gif':
                $return = imagegif( $image, $path );
                break;
        }        

        return $return;
        
    }    
  
    /**
     * Get relative image path, important for PHP opening functions
     * @param string Url = image url
     * @return string Relative Image Path;
     */
    protected static function getRelativePath( $url ) 
    {      
        $rel_path = $url;
        
        // find wp-content start pos
        $s = strpos($url, 'wp-content');
        // get path from wp-content folder to end
        $from_wp_content = substr($url, $s);
        // remove wp-content folder name
        $from_wp_content = str_replace('wp-content', '', $from_wp_content);
        
        $rel_path = WP_CONTENT_DIR.$from_wp_content;
        return $rel_path;    
             
    }    
    /** 
     * Get simple hash created from first and last letters from each folder of the image location - for unique identify every image
     * 
     * @return int Hash
     */
    protected static function getImgHash($path, $img_size, $mode, $filter) 
    {
        $file_size = filesize( $path );
        $hash = $file_size + $img_size['width'] + $img_size['height'] + $mode + $filter;
        return $hash;
    }
    
    /**
     * Get new image absolute path ( with hash, prefix and other ) to check if the image already exists.
     * 
     * @param string $url Url pointing to the image
     * @param string $hash Hash from custom hashing function
     * @param int $width Width of the image
     * @param int $height Height of the image
     * 
     * @return string
     */
    protected static function getNewImagePath($url, $hash, $width, $height) 
    {
        $filename = self::getNewImageName($url, $hash, $width, $height);
        $filepath = self::$upload_dir['basedir']."/{$filename}";
        return $filepath;
    }    
    
    /**
     * Get new image name ( with hash, prefix and other ) to check if the image already exists.
     * 
     * @param string $url Url pointing to the image
     * @param string $hash Hash from custom hashing function
     * @param int $width Width of the image
     * @param int $height Height of the image
     * 
     * @return string
     */    
    protected static function getNewImageName( $url, $hash, $width, $height ) 
    {
        $pinfo = pathinfo( $url );
        
        $filename = $pinfo['filename'];
        $ext = $pinfo['extension'];
        $hash .= '-';

        $suffix = "{$width}x{$height}";
        
        $filepath = "{$hash}{$filename}-{$suffix}.{$ext}";
        return $filepath;
    }
    
    protected static function getNewImageUrl($path, $hash, $width, $height) 
    {
        $new_img_name = self::getNewImageName($path, $hash, $width,$height);
        return( self::$upload_dir['baseurl'] .'/'. $new_img_name );        
    }    
  
    /**
     * Check if upload directory exists, if not, create it. Then load the directories into local variables
     */
    protected static function createDir() 
    {
        // if this directory does not exists, create it;
        if(!is_dir(self::$upload_dir['basedir']))
        {
            mkdir( self::$upload_dir['basedir']);
        }
    }
    
    /**
     * List all the images in the cache folder, and delete the expired images.
     */
    public static function deleteCache() 
    {
        if( self::$enable_caching == false ) return;
        // default timeout is one day :)
        $timeout = self::$caching_interval;
                
        // get all images in the folder and delete the expired images :)        
        $list_of_images = self::readCacheFolder();
        foreach($list_of_images as $one_image ) {
            if ( getimagesize( $one_image['path']) === false )    continue;
            
            $expiring_time = $one_image['time'] + $timeout;
            // we have to delete this shit :)
            if( $expiring_time < time() ) {
                unlink( $one_image['path'] );
            }
        }

    }
    
    /**
     * Go through the whole img store folder and read all files.
     */
    protected static function readCacheFolder() 
    {
        $list_of_elements = array();                // we will be returning this
        $path = self::$upload_dir['basedir'] . '/';
        // go through all elements in the folder and store them in the array
        if ( is_dir( $path ) ) {        
            if ( $dh = opendir( $path ) ) {
                while ( ( $file = readdir($dh) ) !== false) {
                    if( $file == '.' || $file == '..')    continue;

                    $filetype = filetype( $path . $file );
                    if( $filetype == 'file' ) {
                        // store info about element into array, so we dont need to call filetype function again
                        $one_element = array( 'path' => $path.$file, 'type' => $filetype, 'time'=>filemtime($path.$file) );
                        $list_of_elements[] = $one_element;
                    }
                    
                        
                }
                closedir($dh);
            }
        }
        // sort the array A-Z
        sort($list_of_elements);
        // return sorted array
        return $list_of_elements;
    }
}
   
/* DCC_Breadcrumb */
class DCC_Breadcrumb
{         
    public function __construct()
    {
    
    }   
    
    public function wpBreadcrumb($args=array(), $echo=false)
    {
        global $dc_is_page;
        global $dc_page_common_opt;
        global $dc_page;
        global $post;
        
        $def = array(
            'id' => null,
            'level' => 0,
            'type' => '', 
            'title' => null,
            'before_title' => '',   // TODO: Not used at this moment
            'links' => null, // array of name value pairs for additional links
            'empty' => false, // is set to true breadcrumb will be not displayed
            'taxonomy' => '',
            'query_var' => ''
        );
        
        $args = dcf_combineArgs($def, $args);
        $out = '';
         
        $hide_on_page = false;
        if($dc_is_page and $dc_page_common_opt['page_misc_hide_breadcrumb_cbox'])
        {
            $hide_on_page = true;    
        }
        
        if(!GetDCCPI()->getIGeneral()->getOption('breadcrumb_display') or $args['empty'] or $hide_on_page) 
        { 
            $out .= '<div class="dc-wp-breadcrumb-navigation-empty"></div>';
            if($echo) { echo $out; return; } else { return $out; } 
        } 
           
        if($args['level'] == 0)
        {
            $style = '';
     /*
            // TODO: no option "breadcrumb_align" in theme general options
            
            $align = GetDCCPI()->getIGeneral()->getOption('breadcrumb_align');
            if($align == 'left') { $style .= 'text-align:left;'; }
            if($align == 'right') { $style .= 'text-align:right;'; }
            $style = ' style="'.$style.'" ';
     */       
            $out .= '<div class="dc-sixteen dc-columns">'; 
            $out .= '<div class="dc-wp-breadcrumb-navigation" '.$style.'>';
        }
        
        if($args['id'] === null and ($args['type'] == 'post' or $args['type'] == 'page'))
        {            
            $args['id'] = $post->ID;    
        }
        
        $p = null;
        $parent = 0;
        if($args['id'] !== null and ($args['type'] == 'page' and $dc_is_page))
        {    
            global $wpdb;
            $id = $args['id'];
            $p = $wpdb->get_row("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE ID = $id");             
            if(is_object($p))
            {
                $parent = $p->post_parent;
            }        
        }
        
        if($parent != 0)
        {
            $level = $args['level']+1;
            $out .= $this->wpBreadcrumb(array('id' => $parent, 'level' => $level, 'type' => $args['type']), false);    
        } else
        {        
             if(GetDCCPI()->getIGeneral()->getOption('breadcrumb_before_display'))
             {
                $out .= '<span class="before">'; 
                $out .= GetDCCPI()->getIGeneral()->getOption('breadcrumb_before');
                $out .= '</span>';                  
             }   
             
             if(GetDCCPI()->getIGeneral()->getOption('breadcrumb_blog_name_display'))
             {
                $blogname = get_bloginfo('name');
                if(GetDCCPI()->getIGeneral()->getOption('breadcrumb_blog_name_force'))
                {
                    $blogname = GetDCCPI()->getIGeneral()->getOption('breadcrumb_blog_name');   
                }                                
                $out .= '<a class="link" href="'.get_bloginfo('url').'">'.$blogname.'</a>';
                $out .= $this->getBreadcrumbSeprator();
             }
        }  
        
        if($args['level'] == 0)
        {
            if($args['links'] !== null)
            {
                if(is_array($args['links']))
                {                
                    $counter = 0;
                    foreach($args['links'] as $key => $value)
                    {
                        if($counter > 0) { $out .= $this->getBreadcrumbCommaSeprator(); }
                        
                        $href = '';
                        if($value != '') { $href = ' href="'.$value.'" '; }
                        
                        $out .= '<a '.$href.' class="link">'.$key.'</a>';
                        
                        $counter++;    
                    }
                    if($counter) { $out .= $this->getBreadcrumbSeprator(); }     
                }
            }   
            
            if($args['type'] == 'post' or $args['type'] == 'page')
            {
                if($args['taxonomy'] != '')
                {
                    $bc_terms = wp_get_object_terms($post->ID, $args['taxonomy']);                
                    $out .= $this->getBreadcrumbTaxonomy(array('terms' => $bc_terms, 'taxonomy' => $args['taxonomy']));                               
                }     
            }
            
            if($args['type'] == 'category' or $args['type'] == 'tag')
            {
                if($args['type'] == 'category')
                {                
                    if($args['taxonomy'] == '') { $args['taxonomy'] = 'category'; } 
                    if($args['query_var'] == '') { $args['query_var'] = 'cat'; }                                         
                }

                if($args['type'] == 'tag')
                {
                    if($args['taxonomy'] == '') { $args['taxonomy'] = 'post_tag'; }
                    if($args['query_var'] == '') { $args['query_var'] = 'tag_id'; }                  
                }                            
                
                if(($args['taxonomy'] != '') and ($args['query_var'] != ''))
                {       
                    $term = '';
                    $term_id = 0;
                       
                    if(($args['taxonomy'] == 'category') or ($args['taxonomy'] == 'post_tag'))
                    {
                        $term_id = (get_query_var($args['query_var'])) ? get_query_var($args['query_var']) : ''; 
                        $term = get_term($term_id, $args['taxonomy']);    
                        $args['title'] = $term->name;                     
                    } else            
                    {                    
                        $term_slug = (get_query_var($args['query_var'])) ? get_query_var($args['query_var']) : ''; 
                        $term = get_term_by('slug', $term_slug, $args['taxonomy'], OBJECT);    
                        $term_id = $term->term_id;
                        $args['title'] = $term->name;                                               
                    }
                                    
                    $out .= $this->getBreadcrumbTaxonomy(array('terms' => array(0 => $term), 'taxonomy' => $args['taxonomy'], 'exclude_id' => $term_id));   
                    
                }
            }                          
            
            if($args['title'] === null)
            {   
                if($parent != 0) { $out .= $this->getBreadcrumbSeprator(); }
                $out .= '<span class="selected">'.$post->post_title.'</span>';
            } else
            {   
                if($parent != 0) { $out .= $this->getBreadcrumbSeprator(); }
                $out .= '<span class="selected">'.$args['title'].'</span>';
            }
            
            $out .= '</div>'; 
            $out .= '</div>'; 
        } else
        {
            if($parent != 0) { $out .= $this->getBreadcrumbSeprator(); }
            $out .= '<a href="'.get_permalink($p->ID).'" class="link">'.$p->post_title.'</a>';
        }    
        
        
        
        if($echo) { echo $out; } else { return $out; }          
    }
    
    private function getBreadcrumbTaxonomy($args=array(), $echo=false)
    {
        $def = array(
            'terms' => array(),
            'taxonomy' => '',
            'exclude_id' => 0 
        );    
        $args = dcf_combineArgs($def, $args);
        $out = '';
    
        if(is_array($args['terms']))
        {           
            if(count($args['terms']))
            {         
            
                $tree = $this->getBreadcrumbTermsTree(array('terms' => $args['terms'], 'taxonomy' => $args['taxonomy']));
                $list = array();
                
                foreach($tree as $t)
                {
                    if($t->parent == 0) { array_push($list, $t); }                    
                }
                            
                while(count($list))
                {            
                    $new_list = array();
                    $counter = 0;                                               
                    foreach($list as $t)
                    {
                        if($t->term_id == $args['exclude_id']) { continue; }  
                        
                        if($counter > 0) { $out .= $this->getBreadcrumbCommaSeprator(); }
                        $out .= '<a href="'.get_term_link($t->slug, $t->taxonomy).'" class="link">'.$t->name.'</a>';
                        $counter++;    

                        foreach($tree as $tt)
                        {
                            if($tt->parent == $t->term_id)
                            {
                                array_push($new_list, $tt);
                            }    
                        }                    
                    }
                    if($counter) { $out .= $this->getBreadcrumbSeprator(); } 
                    $list = $new_list;                       
                }
            }
        }           
        
        if($echo) { echo $out; } else { return $out; }
    }
    
    private function getBreadcrumbTermsTree($args=array())
    {
        $def = array(
            'terms' => array(),
            'taxonomy' => ''
        );
        $args = dcf_combineArgs($def, $args);
        
        $terms = array();
        if(is_array($args['terms']))
        {
            foreach($args['terms'] as $t)
            {
                array_push($terms, $t); 
                if($t->parent)
                {                    
                    $max = 20;
                    while($t->parent and $max)
                    {                            
                        $t = get_term($t->parent, $args['taxonomy']);
                        array_push($terms, $t);
                        $max--;
                    }                         
                }
            }                                  
        }
        
        // remove doubled terms
        $new = array();
        foreach($terms as $t)
        {
            $has = false;
            foreach($new as $tn)
            {
                if($tn->term_id == $t->term_id) { $has = true; }
            }    
            if(!$has) { array_push($new, $t); }
        }
        
        $terms = $new;        
        return $terms;
    }
    
    private function getBreadcrumbSeprator($echo=false)
    {
        $out = '<span class="separator">/</span>';
        
        if($echo) { echo $out; } else { return $out; }
    }   

    private function getBreadcrumbCommaSeprator($echo=false)
    {
        $out = '<span class="comma-separator">,</span>';
        
        if($echo) { echo $out; } else { return $out; }
    }     
     
}        
        
?>
