<?php

/**
 * Semantic Classes is made up of class-generating functions
 * that dynamically generate context sensitive classes and ids
 * to give unprecedented control over your layout options via CSS.
 * 
 * @package EvoLve
 * @subpackage Semantic_Markup
 */
/**
 * Functions:
 * semantic_body();
 * semantic_entries();
 * semantic_comments();
 * semantic_last_class();
 */
/* Define the num val for 'alt' classes (in post DIV and comment LI) */
$semantic_post_alt = 1;
$semantic_comment_alt = 1;

/**
 * semantic_body() - Generates semantic classes for <body> element
 *
 * @since - 0.2
 * @filter semantic_body
 * @uses semantic_time()
 */
function semantic_body($classes = array()) {
    global $wp_query, $current_user;

    //$classes = get_body_class();
    // Starts the semantic markup array
    $sc = array('EvoLve');

    // Generic semantic classes for what type of content is displayed
    is_front_page() ? $classes[] = 'home' : null; // For the front page, if set
    is_home() ? $classes[] = 'blog' : null; // For the blog posts page, if set
    is_singular() ? $classes[] = 'singular' : null;
    is_single() ? $classes[] = 'single' : null;
    is_archive() ? $classes[] = 'archive' : null; // For archive based templates: archive.php, author.php, category.php, tag.php
    is_date() ? $classes[] = 'date' : null;
    is_search() ? $classes[] = 'search' : null;
    is_paged() ? $classes[] = 'paged' : null;
    is_attachment() ? $classes[] = 'attachment' : null;
    is_404() ? $classes[] = 'error404' : null;

    // Applies the time- and date-based classes (below) to BODY element
    // Special classes for BODY element when a single post
    if (is_single()) {
        $postID = $wp_query->post->ID;
        the_post();

        // Adds 'single' class and class with the post ID
        $sc[] = 'single postid-' . $postID;

        // Adds classes for the month, day, and hour when the post was published
        // Adds MIME-specific classes for attachments
        if (is_attachment()) {
            $mime_type = get_post_mime_type();
            $mime_prefix = array('application/', 'image/', 'text/', 'audio/', 'video/', 'music/');
            $sc[] = 'attachmentid-' . $postID . ' attachment-' . str_replace($mime_prefix, "", "$mime_type");
        }

        // Adds category classes for each category on single posts
        if ($cats = get_the_category())
            foreach ($cats as $cat)
                if ($cat)
                    $classes[] = 's-category-' . $cat->slug;
                else
                    $classes[] = 's-category-none';

        // Adds tag classes for each tags on single posts
        if ($tags = get_the_tags())
            foreach ($tags as $tag)
                if ($tag)
                    $classes[] = 's-tag-' . $tag->slug;
                else
                    $classes[] = 's-tag-none';

        // Adds author class for the post author
        if (the_author_meta('login'))
            $s_author = sanitize_title_with_dashes(strtolower(the_author_meta('login')));
        else
            $s_author = 'none';
        $classes[] = 's-author-' . $s_author;
        rewind_posts();
    }

    // Author name classes for BODY on author archives
    elseif (is_author()) {
        $author = $wp_query->get_queried_object();
        $classes[] = 'author';
        if ($author)
            $classes[] = 'author-' . $author->user_nicename;
        else
            $classes[] = 'author-none';
    }

    // Category name classes for BODY on category archvies
    elseif (is_category()) {
        $cat = $wp_query->get_queried_object();
        $classes[] = 'category';
        if ($cat)
            $classes[] = 'category-' . $cat->slug;
        else
            $classes[] = 'category-none';
    }

    // Tag name classes for BODY on tag archives
    elseif (is_tag()) {
        $tags = $wp_query->get_queried_object();
        $classes[] = 'tag';
        if ($tags)
            $classes[] = 'tag-' . $tags->slug;
        else
            $classes[] = 'tag-none';
    }

    // Page author for BODY on 'pages'
    elseif (is_page()) {
        $pageID = $wp_query->post->ID;
        $page_children = wp_list_pages("child_of=$pageID&echo=0");
        if (!$pageID)
            $pageID = 0;
        $page_children = 0;

        the_post();

        $classes[] = 'page pageid-' . $pageID;
        // Checks to see if the page has children and/or is a child page; props to Adam
        if ($page_children)
            $classes[] = 'page-parent';
        if ($wp_query->post->post_parent)
            $classes[] = 'page-child parent-pageid-' . $wp_query->post->post_parent;
        if (is_page_template())
            $classes[] = 'page-template page-template-' . str_replace('.php', '-php', get_post_meta($pageID, '_wp_page_template', true));

        rewind_posts();
    }

    // Page author for BODY on 'pages'
    elseif (is_page()) {
        $pageID = $wp_query->post->ID;
        $page_children = wp_list_pages("child_of=$pageID&echo=0");
        the_post();
        $sc[] = 'page pageid-' . $pageID;
        // Checks to see if the page has children and/or is a child page; props to Adam
        if ($page_children)
            $sc[] = 'page-parent';
        if ($wp_query->post->post_parent)
            $sc[] = 'page-child parent-pageid-' . $wp_query->post->post_parent;
        if (is_page_template()) // Hat tip to Ian, themeshaper.com
            $sc[] = 'page-template page-template-' . str_replace('.php', '-php', get_post_meta($pageID, '_wp_page_template', true));
        rewind_posts();
    }

    // Search classes for results or no results
    elseif (is_search()) {
        the_post();

        if (have_posts())
            $sc[] = 'search-results';
        else
            $sc[] = 'search-no-results';

        rewind_posts();
    }

    // For when a visitor is logged in while browsing
    if ($current_user->ID)
        $sc[] = 'loggedin';

    // Paged classes; for 'page X' classes of index, single, etc.
    if (( ( $page = $wp_query->get('paged') ) || ( $page = $wp_query->get('page') ) ) && $page > 1) {
        $sc[] = 'paged-' . $page;
        if (is_single())
            $sc[] = 'single-paged-' . $page;
        elseif (is_page())
            $sc[] = 'page-paged-' . $page;
        elseif (is_category())
            $sc[] = 'category-paged-' . $page;
        elseif (is_tag())
            $sc[] = 'tag-paged-' . $page;
        elseif (is_date())
            $sc[] = 'date-paged-' . $page;
        elseif (is_author())
            $sc[] = 'author-paged-' . $page;
        elseif (is_search())
            $sc[] = 'search-paged-' . $page;
    }

    $classes = join(' ', apply_filters('semantic_body', $classes)); // Available filter: semantic_body
    $print = apply_filters('semantic_body_print', false); // Available filter: semantic_body_print
    // And tada!
    if (!$print)
        echo $classes;
    else
        return $classes;
}

/**
 * semantic_entries() - Generates semantic classes for each post <div> element
 *
 * @since - 0.2
 * @filter semantic_entries
 * @uses semantic_time()
 */
function semantic_entries($classes = array()) {
    global $post, $semantic_post_alt, $entry_first_class;

    // Let WordPress do all the heavy lifting
    $classes[] = join(' ', get_post_class());

    // Gets 'alt' for every other post DIV, p[n] and post status
    $classes[] = "p$semantic_post_alt";
    $classes[] = $post->post_status;

    // add css class to first comment
    if ($entry_first_class == 0)
        $classes[] = 'first-' . $post->post_type;
    $entry_first_class = 1;

    // Author for the post queried


    if (get_the_category($post->ID) != null) {
        $classes[] = 'cat';
    }

    // Tags for the post queried; if not tagged, use .untagged
    if (get_the_tags($post->ID) == null)
        $classes[] = 'untagged';
    else
        $classes[] = 'tag';

    // For password-protected posts
    if ($post->post_password)
        $classes[] = 'protected';

    // Applies the time- and date-based classes
    // If it's the other to the every, then add 'alt' class
    if (++$semantic_post_alt % 2 && !is_singular())
        $classes[] = 'alt';

    $classes = join(' ', apply_filters('semantic_entries', $classes)); // Available filter: semantic_entries
    $print = apply_filters('semantic_entries_print', false); // Available filter: semantic_entries_print
    // And tada!
    if (!$print)
        echo $classes;
    else
        return $classes;
}

/**
 * semantic_comments() - Generates semantic classes for each comment <li> element
 *
 * @since - 0.2
 * @filter semantic_comments
 * @uses semantic_time()
 */
function semantic_comments($classes = array()) {
    global $comment, $post, $wpdb, $current_user, $comment_first_class, $semantic_comment_alt;

    // Collects the comment type (comment, trackback)
    $classes[] = get_comment_type();

    // add css class to first comment
    if ($comment_first_class == 0)
        $classes[] = 'first-comment';
    $comment_first_class = 1;

    // add css class to last comment
    if ($comment->comment_ID == semantic_last_class('comment') and ! $comment_first_class)
        $classes[] = 'last-comment';

    // Show commenter's capabilities
    if ($comment->user_id > 0 && $user = get_userdata($comment->user_id)) {
        $capabilities = $user->{$wpdb->prefix . 'capabilities'}; // hat tip to Justin Tadlock http://www.themehybrid.com

        if (array_key_exists('administrator', $capabilities))
            $classes[] = 'administrator administrator-' . $user->user_login;
        elseif (array_key_exists('editor', $capabilities))
            $classes[] = 'editor editor-' . $user->user_login;
        elseif (array_key_exists('author', $capabilities))
            $classes[] = 'author author-' . $user->user_login;
        elseif (array_key_exists('contributor', $capabilities))
            $classes[] = 'contributor contributor-' . $user->user_login;
        elseif (array_key_exists('subscriber', $capabilities))
            $classes[] = 'subscriber subscriber-' . $user->user_login;
    } else
        $classes[] = 'reader reader-' . str_replace(' ', '-', strtolower($comment->comment_author));

    // http://microid.org
    $email = get_comment_author_email();
    $uri = get_comment_author_url();
    if (!empty($email) && !empty($uri)) {
        if (preg_match('/https:\/\//i', $uri))
            $protocal = 'https';
        elseif (preg_match('/http:\/\//i', $uri))
            $protocal = 'http';
        $microid = "microid-mailto+{$protocal}:sha1:" . sha1(sha1('mailto:' . $email) . sha1($uri));
        $classes[] = $microid;
    }

    // If it's the other to the every, then add 'alt' class; collects time- and date-based classes


    $classes = join(' ', apply_filters('semantic_comments', $classes)); // Available filter: semantic_comments
    $print = apply_filters('semantic_comments_print', false); // Available filter: semantic_comments_print
    // And tada!
    if (!$print)
        echo $classes;
    else
        return $classes;
}

/**
 * semantic_last_class() - returns the ID for the last class.
 *
 * @since - 0.3
 */
function semantic_last_class($type = NULL) {
    global $comment, $post, $wpdb;
    if (!$type == 'comment' || !$type == 'post')
        return;

    $post_id = $post->ID;

    // type can be post/comment (W.I.P.)
    if ($type == 'comment')
        $query = "SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post_id";

    if ($type)
        $get_id = $wpdb->get_results($query, ARRAY_N);

    $last = end($get_id);
    return $last[0];
}

/* Remember: Semantic Classes, like the Sandbox, is for play. (-_^) */
