<?php
// $Id: taxonomy_theme.module,v 1.6.x.x 2006/04/18 16:28:34 profix898 Exp $

define('TAXOTHEME_SKIP',     0);
define('TAXOTHEME_TERM',     1);
define('TAXOTHEME_VOCAB',    2);
define('TAXOTHEME_ALLTAXO',  3);
define('TAXOTHEME_NODETYPE', 4);

/**
 * Implementation of hook_help().
 */
function taxonomy_theme_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Assign themes to pages by mapping taxonomy vocabs/terms to themes.');
  }
}

/**
 * Implementation of hook_settings().
 */
function taxonomy_theme_settings() {
  // check for taxonomy.module being enabled
  if (!module_exist('taxonomy')) {
    return t('Please enable the taxonomy module.'); 
  } 
  // TaxonomyTheme enable/disable
  if (!variable_get('taxonomy_theme_enable', 0)) {
    $block_output = form_radios(t('Taxonomy-based templates'), 'taxonomy_theme_enable', variable_get('taxonomy_theme_enable', 0), array(t('Disabled'), t('Enabled')));
    return $block_output;
  }
  $block_output = form_checkbox(t('Taxonomy-based templates'), 'taxonomy_theme_enable', 1, variable_get('taxonomy_theme_enable', 0));
  
  $block_output .= form_checkbox(t('Allow all themes'), 'taxonomy_theme_allowall', 1, variable_get('taxonomy_theme_allowall', 0), t('Offers all installed themes for selection, not enabled ones only.'));
  
  $themes = list_themes();
  $options_admin_themes = array();
  $options_themes = array();
  foreach ($themes as $themex) {
    $options_admin_themes[$themex->name] = $themex->name;
    if ($themex->status || variable_get('taxonomy_theme_allowall', 0)) {
      $options_themes[$themex->name] = $themex->name;
    }
  }

  // AdminTheme
  $rows = array();
  $rows[] = array(t('\'Admin Area\' - Theme'), form_select('', 'taxonomy_theme_admin', variable_get('taxonomy_theme_admin', variable_get('theme_default', 'bluemarine')), $options_admin_themes));
  $block_output .= theme('table', array(), $rows);
  
  // TaxonomyTheme selection method
  $options = array();
  $options[0] = t('Choose method');
  $options[1] = t('Term-based');
  $options[2] = t('Vocab-based');
  $options[3] = t('All Taxonomy');
  $options[4] = t('NodeType-based');
  $method = variable_get('taxonomy_theme_method', TAXOTHEME_SKIP);
  $block_output .= form_select(t('Template selection method'), 'taxonomy_theme_method', $method, $options, t('This value determines the method used for template selection.'));
  
  $output = form_group(t('Global Module Setup'), $block_output);
  $forum_vid = variable_get('forum_nav_vocabulary', '');
  
  switch($method) {
  // BLOCK: term based selection
  case TAXOTHEME_TERM:
    $options = array();
    $selector = variable_get('taxonomy_theme_selector', '');
    if (!$selector) {
      $options[0] = t('Choose a category');
    }
    $vocabs = taxonomy_get_vocabularies();
    foreach ($vocabs as $vocab) {
      if ($vocab->vid != $forum_vid) {
        $options[$vocab->vid] = $vocab->name;
      }
    }
    if (!empty($vocabs)) {
      $block_output = form_select(t('Category to use for template selection'), 'taxonomy_theme_selector', $selector, $options, t('The value of this category will be used to determine the template to apply.'));
    } else {
      $block_output = t('<br /><strong>Your site currently has no categories.</strong><br /><br />Please create at least one category and add the terms you will map to themes and return to this page. For example, you might create a category called Sections that has two terms, <em>blue</em> to map to the bluebeach theme and <em>grey</em> to map to the <em>box_grey</em> theme.<br />'); 
    }
    if ($selector) {
      $terms = taxonomy_get_tree($selector);
      if (count($terms)) {
        $rows = array();
        $header = array(t('Term'), t('Assigned to Theme'));
        foreach ($terms as $term) {
          $template_this_term = variable_get('taxonomy_theme_term|'.$term->tid, '');
          $options_this_term = $options_themes;
          if (!$template_this_term) {
            $options_this_term[0] = t('Choose a template'); 
          }
          $rows[] = array($term->name, form_select('', 'taxonomy_theme_term|'.$term->tid, $template_this_term, $options_this_term));
        }
        $block_output .= theme('table', $header, $rows);
      } else {
        $block_output .= t('<strong>No items</strong>');
      }
    }
    $output .= form_group(t('Terms => Themes'), $block_output);
    break;
  // BLOCK: vocab based selection 
  case TAXOTHEME_VOCAB:
    $vocabs = taxonomy_get_vocabularies();
    if (count($vocabs)) {
      $rows = array();
      $header = array(t('Vocabulary'), t('Assigned to Theme'));
      foreach ($vocabs as $vocab) {
        $template_this_vocab = variable_get('taxonomy_theme_vocab|'.$vocab->vid, '');
        $options_this_vocab = $options_themes;
        if (!$template_this_vocab) {
          $options_this_vocab[0] = t('Choose a template'); 
        }
        $rows[] = array($vocab->name, form_select('', 'taxonomy_theme_vocab|'.$vocab->vid, $template_this_vocab, $options_this_vocab));
      }
      $block_output = theme('table', $header, $rows); 
    } else {
      $block_output = t('<strong>Your site currently has no vocabularies.</strong>');
    }
    $output .= form_group(t('Vocabularies => Themes'), $block_output);  
    break;
  // BLOCK: all taxonomy selection 
  case TAXOTHEME_ALLTAXO:
    $vocabs = taxonomy_get_vocabularies();
    if (count($vocabs)) {
      $block_output = '';
      foreach ($vocabs as $vocab) {
        if ($vocab->vid != $forum_vid) {
          $terms = taxonomy_get_tree($vocab->vid);
          if (count($terms)) {
            $rows = array();
            $header = array(t('Term'), t('Assigned to Theme'));
            foreach ($terms as $term) {
              $template_this_term = variable_get('taxonomy_theme_all|'.$term->tid, '');
              $options_this_term = $options_themes;
              if (!$template_this_term) {
                $options_this_term[0] = t('Choose a template');
              }
              $rows[] = array($term->name, form_select('', 'taxonomy_theme_all|'.$term->tid, $template_this_term, $options_this_term));
            }
            $group = theme('table', $header, $rows);
      		  $block_output .= form_group(t('Vocabulary: ').$vocab->name, $group);
    		  } else {
            $block_output .= t('<strong>No items</strong>');
          }
        }
      }
    } else {
      $block_output = t('<strong>Your site currently has no vocabularies.</strong>');
    }
    $output .= form_group(t('All Taxonomy => Themes'), $block_output);
    break;
  // BLOCK: node type based selection 
  case TAXOTHEME_NODETYPE:
    $nodetypes = node_list();
    if (count($nodetypes)) {
      $rows = array();
      $header = array(t('NodeType'), t('Assigned to Theme'));
      var_dump($nodetypes);
      foreach ($nodetypes as $type) {
        $template_this_type = variable_get('taxonomy_theme_nodetype|'.$type, '');
        $options_this_type = $options_themes;
        if (!$template_this_type) {
          $options_this_type[0] = t('Choose a template'); 
        }
        $rows[] = array($type, form_select('', 'taxonomy_theme_nodetype|'.$type, $template_this_type, $options_this_type));
      }
      $block_output = theme('table', $header, $rows);
    } else {
      $block_output = t('<strong>Your site currently has no node type defined.</strong>');
    }
    $output .= form_group(t('NodeType => Themes'), $block_output);
    break;
  default:
    $output .= t('<br /><strong>Select one method from above.</strong><br />');
  }
    
  // BLOCK: forums 
  if (module_exist('forum')) {
    $block_output = form_checkbox(t('Apply themes to forums'), 'taxonomy_theme_forums_enable', 1, variable_get('taxonomy_theme_forums_enable', 0));
    if (variable_get('taxonomy_theme_forums_enable', 0)) {
      $block_output .= form_checkbox(t('Theme forum-dependent nodes/pages'), 'taxonomy_theme_forum_dep', 1, variable_get('taxonomy_theme_forum_dep', 1), t('Apply the forum\'s theme to (add/view/edit) comment pages also.'));
      $terms = taxonomy_get_tree($forum_vid);
      if (count($terms)) {
        $rows = array();
        $header = array(t('Forum'), t('Assigned to Theme'));
        foreach ($terms as $forum) {
          $template_this_forum = variable_get('taxonomy_theme_forum|'.$forum->tid, '');
          $options_this_forum = $options_themes;
          if (!$template_this_forum) {
            $options_this_forum[0] = t('Choose a template'); 
          }
          $rows[] = array($forum->name, form_select('', 'taxonomy_theme_forum|'.$forum->tid, variable_get('taxonomy_theme_forum|'.$forum->tid, ''), $options_this_forum));
        }
        $block_output .= theme('table', $header, $rows);
      } else {
        $block_output .=  t('<strong>Your site currently has no forums.</strong>');
      }
    }
    $output .= form_group(t('Forums Themes'), $block_output);
  }
  
  $block_output = form_checkbox(t('Enable \'Extended\' assignment of themes'), 'taxonomy_theme_extended_enable', 1, variable_get('taxonomy_theme_extended_enable', 0), t('Enables you to assign themes to pathes (e.g. node/21).'));
  if (variable_get('taxonomy_theme_extended_enable', 0)) {
    foreach($options_admin_themes as $theme) {
      $block_output .= form_textarea($theme, 'taxonomy_theme_path|'.$theme, variable_get('taxonomy_theme_path|'.$theme, ''), 60, 5);
    }
    $block_output .= t('<p>To assign a theme for a particular path enter the path into according textarea.<br />Enter one page per line as Drupal paths. The \'*\' character is a wildcard.<br /><i>Adding \'node/6\' to the \'bluemarine\' field will assign bluemarine theme to node 6.</i></p>');
  }  
  $output .= form_group(t('Extended'), $block_output);
  
  return $output;
}

/**
 * Implementation of hook_init().
 */
function taxonomy_theme_init() {
  // check dependencies
  if(!module_exist('taxonomy') || !variable_get('taxonomy_theme_enable', 0)) {
    return;
  }
  // BEGIN: change theme
  global $custom_theme, $user;
  $uri = $_GET['q'];
  $default_theme = variable_get('theme_default', 'bluemarine');
  $theme_method = variable_get('taxonomy_theme_method', TAXOTHEME_SKIP);
  // change theme for admin area
  if(ereg('^admin', $uri)) {
    $custom_theme = variable_get('taxonomy_theme_admin', $default_theme);
    $theme_method = TAXOTHEME_SKIP;
  }
  // theme forum dependent pages/nodes
  $forum_vid = variable_get('forum_nav_vocabulary', '');
  $theme_forums = (module_exist('forum') && variable_get('taxonomy_theme_forums_enable', 0));
  $theme_forum_dep = ($theme_forums && variable_get('taxonomy_theme_forum_dep', 1));
  if ($theme_forum_dep) {
    if (ereg('^node/add/forum/', $uri)) {
      $fid = basename($uri);
      $custom_theme = variable_get('taxonomy_theme_forum|'.$fid, $default_theme);
      $theme_method = TAXOTHEME_SKIP;
    }
    if (preg_match('#comment/reply/([0-9]*).*#', $uri, $matches)) {
      $term = db_fetch_object(db_query('SELECT tid FROM {forum} WHERE nid = %d', $matches[1]));
      if ($term) {
        $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
        $theme_method = TAXOTHEME_SKIP;
      }
    }
    if (preg_match('#comment/(delete|edit)/([0-9]*).*#', $uri, $matches)) {
      $term = db_fetch_object(db_query('SELECT f.tid FROM {forum} f INNER JOIN {comments} c ON f.nid = c.nid WHERE c.cid = %d', $matches[2]));
      if ($term) {
        $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
        $theme_method = TAXOTHEME_SKIP;
      }
    }
  }
  switch ($theme_method) {
  // BLOCK: term based selection
  case TAXOTHEME_TERM:
    $selector_vid = variable_get('taxonomy_theme_selector', '');
    if ((arg(0) == 'node') && is_numeric(arg(1))) {
      $nid = arg(1);
      $terms = taxonomy_node_get_terms_by_vocabulary($nid, $selector_vid);
      if ($terms) {
        $term = current($terms);
        $custom_theme = variable_get('taxonomy_theme_term|'.$term->tid, $default_theme);
      } else if ($theme_forum_dep) {
        $term = db_fetch_object(db_query('SELECT tid FROM {forum} WHERE nid = %d', $nid));
        $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
      }
    } else if ((arg(0) == 'taxonomy_menu') && (arg(1) == $selector_vid) && arg(2)) {
      $tid = basename($uri);
      $custom_theme = variable_get('taxonomy_theme_term|'.$tid, $default_theme);
    } else if ((arg(0) == 'taxonomy') && (arg(1) == 'term')) {
      if (is_numeric(arg(2))) {
        $tid = arg(2);
        $tobj = taxonomy_get_term($tid);
        if ($tobj->vid == $selector_vid) {
          $custom_theme = variable_get('taxonomy_theme_term|'.$tid, $default_theme);
        } else if ($tobj->vid == $forum_vid) {
          $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
        }
      }
    } else if ((arg(0) == 'forum') && is_numeric(arg(1)) && $theme_forums) {
      $tid = arg(1);
      $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
    }
    break;
  // BLOCK: vocab based selection 
  case TAXOTHEME_VOCAB:
    if ((arg(0) == 'node') && is_numeric(arg(1))) {
      $nid = arg(1);
      $terms = taxonomy_node_get_terms($nid);
      $term = current($terms);
      $vid = $term->vid;
      $custom_theme = variable_get('taxonomy_theme_vocab|'.$vid, $default_theme);
      if ($theme_forum_dep && ($vid == $forum_vid)) {
        $term = db_fetch_object(db_query('SELECT tid FROM {forum} WHERE nid = %d', $nid));
        $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
      }
    } else if ((arg(0) == 'taxonomy_menu') && is_numeric(arg(1))) {
      $vid = arg(1);
      if ($theme_forums && ($vid == $forum_vid)) {
        $tid = basename($uri);
        $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
      } else {      
        $custom_theme = variable_get('taxonomy_theme_vocab|'.$vid, $default_theme);
      }
    } else if ((arg(0) == 'taxonomy')) {
      if (is_numeric(arg(2))) {
        $tid = arg(2);
        $tobj = taxonomy_get_term($tid);
        $vid = $tobj->vid;
        if ($theme_forums && ($vid == $forum_vid)) {
          $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
        } else {      
          $custom_theme = variable_get('taxonomy_theme_vocab|'.$vid, $default_theme);
        }
      }
    } else if ((arg(0) == 'forum') && is_numeric(arg(1)) && $theme_forums) {
      $tid = arg(1);
      $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
    }
    break;
  // BLOCK: all taxonomy selection 
  case TAXOTHEME_ALLTAXO:
    if ((arg(0) == 'node') && is_numeric(arg(1))) {
      $nid = arg(1);
      $terms = taxonomy_node_get_terms($nid);
      $term = current($terms);
      $vid = $term->vid;
      $custom_theme = variable_get('taxonomy_theme_all|'.$term->tid, $default_theme);
      if ($theme_forum_dep && ($vid == $forum_vid)) {
        $term = db_fetch_object(db_query('SELECT tid FROM {forum} WHERE nid = %d', $nid));
        $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
      }
    } else if ((arg(0) == 'taxonomy_menu') && arg(2)) {
      $tid = basename($uri);
      $custom_theme = variable_get('taxonomy_theme_all|'.$tid, $default_theme);
    } else if ((arg(0) == 'taxonomy')) {
      if (is_numeric(arg(2))) {
        $tid = arg(2);
        $tobj = taxonomy_get_term($tid);
        $custom_theme = variable_get('taxonomy_theme_all|'.$tid, $default_theme);
        if ($tobj->vid == $forum_vid) {
          $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
        }
      }
    } else if ((arg(0) == 'forum') && is_numeric(arg(1)) && $theme_forums) {
      $tid = arg(1);
      $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
    }
    break;
  // BLOCK: node type based selection 
  case TAXOTHEME_NODETYPE:
    if ((arg(0) == 'node') && is_numeric(arg(1))) {
      $nid = arg(1);
      $nodetype = db_fetch_object(db_query('SELECT type FROM {node} WHERE nid = %d', $nid));
      if ($nodetype->type) {
        $custom_theme = variable_get('taxonomy_theme_nodetype|'.$nodetype->type, $default_theme);
        if (($nodetype->type == 'forum topic') && $theme_forum_dep) {
          $term = db_fetch_object(db_query('SELECT tid FROM {forum} WHERE nid = %d', $nid));
          $custom_theme = variable_get('taxonomy_theme_forum|'.$term->tid, $default_theme);
        }
      }
    } else if ((arg(0) == 'forum') && is_numeric(arg(1)) && $theme_forums) {
      $tid = arg(1);
      $custom_theme = variable_get('taxonomy_theme_forum|'.$tid, $default_theme);
    }
    break;
  default:
    // TAXOTHEME_SKIP or nothing to do
  } 
  // extended assignment
  if (variable_get('taxonomy_theme_extended_enable', 0)) {
    $themes = list_themes();
    foreach ($themes as $themex) {
      $pathes_raw = variable_get('taxonomy_theme_path|'.$themex->name, '');
      if (!empty($pathes_raw)) {
        $pathes = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($pathes_raw, '/')) .')$/';
        if (preg_match($pathes, $uri)) {
          $custom_theme = $themex->name;
        }
      }
    }
  }
  // only apply for theme != default theme (users can have own default theme)
  if (isset($custom_theme) && ($custom_theme != $default_theme)) {
    init_theme();
  }
  // END: change theme
}
