package com.usemodj.forum;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.usemodj.forum.domain.Forum;
/*
*
function bb_get_forums_hierarchical( $root = 0, $depth = 0, $leaves = false, $_recursed = false ) {
static $_leaves = false;
if (!$_recursed)
$_leaves = false;
$root = (int) $root;
if ( false === $_leaves )
$_leaves = $leaves ? $leaves : bb_get_forums();
if ( !$_leaves )
return false;
$branch = array();
reset($_leaves);
while ( list($l, $leaf) = each($_leaves) ) {
if ( $root == $leaf->forum_parent ) {
$new_root = (int) $leaf->forum_id;
unset($_leaves[$l]);
$branch[$new_root] = 1 == $depth ? true : bb_get_forums_hierarchical( $new_root, $depth - 1, false, true );
reset($_leaves);
}
}
if ( !$_recursed ) {
if ( !$root )
foreach ( $_leaves as $leaf ) // Attach orphans to root
$branch[$leaf->forum_id] = true;
$_leaves = false;
return ( empty($branch) ? false : $branch );
}
return $branch ? $branch : true;
}
*/
public class ForumsHierarchical {
private static Logger logger = Logger.getLogger( ForumsHierarchical.class);
Map<Long, Forum> _leaves = null;
BBLoop forumsLoop = null;
Forum forum;
Map<String, Integer> bbAlt = new HashMap();
public Map getForumsHierarchical( int root, int depth, Map leaves, boolean recursed ) {
if( ! recursed)
_leaves = null;
if( null == _leaves) // 'child_of' => 0, 'hierarchical' => 0, 'depth' => 0, 'cut_branch' => 0
//_leaves = (null != leaves)? leaves : getForumsMap( 0, 0, 0, 0);
_leaves = leaves;
if( null == _leaves)
return null; // false
Map<Long, Map<?, ?>> branch = new LinkedHashMap();
RESET: for(;;) {
for( Map.Entry<Long, Forum> entry : _leaves.entrySet()){
Long k = entry.getKey();
Forum leaf = entry.getValue();
if( root == leaf.getForumParent()) {
int newRoot = leaf.getForumId();
_leaves.remove( k);
branch.put( (long)newRoot, (1 == depth)? Collections.EMPTY_MAP : getForumsHierarchical( newRoot, depth -1, null, true)); // true : Collection.EMPTY_MAP
continue RESET;
}
}
break RESET;
} //end of for(;;)
logger.debug("== ForumsHierachical : branch: " + branch.toString());
if( !recursed){
if( 0 == root)
for( Forum leaf : _leaves.values()) // Attach orphans to root
branch.put( (long)leaf.getForumId(), Collections.EMPTY_MAP); //true
_leaves.clear();
_leaves = null;
return ( branch.isEmpty()? null : branch); //false
}
return null != branch? branch: Collections.EMPTY_MAP; //true
}
/**
*
* $defaults = array( 'callback' => false, 'callback_args' => false, 'child_of' => 0, 'hierarchical' =>1, 'depth' => 0, 'cut_branch' => 0, 'where' => '', 'order_by' => 'forum_order' );
* @param forums
* @param childOf
* @param hierarchical
* @param depth
* @param cutBranch
* @return
*/
public Map getForumsMap( Map forums, int childOf, int hierarchical, int depth, int cutBranch){
if( childOf > 0 || hierarchical > 0 || depth > 0) {
Map<Long, Object> _forums = getForumsHierarchical( childOf, depth, new LinkedHashMap(forums), false);
if( null != _forums)
logger.debug(" ===getForumsHierarchical () results: \n"+ _forums.toString());
if( null != forums)
logger.debug("=== forums: "+ forums.toString() );
_forums = getFlattenMap( _forums, cutBranch, true);
if( null == _forums) return null;
for( Long k : _forums.keySet())
_forums.put( k, forums.get( k));
forums = _forums;
}
return forums;
}
public Map<Long, Object> getFlattenMap( Map<Long, Object> forums, int cutBranch, boolean keepChildMapKeys) {
if( null == forums || forums.isEmpty())
//return Collections.EMPTY_MAP;
return null;
Map temp = new LinkedHashMap();
for( Map.Entry<Long, Object> entry: forums.entrySet() ) {
Long k = (Long)entry.getKey();
Object v = entry.getValue();
if( 0 != cutBranch && k.equals( cutBranch))
continue;
logger.debug(" ==== ForumsHierarchical.getFlattenMap : key => value\n"+ k + " => "+ v.toString());
if( v instanceof Map /*&& !((Map) v).isEmpty()*/) {
if( keepChildMapKeys)
temp.put(k, true);
Map fm = getFlattenMap( (Map)v, cutBranch, keepChildMapKeys);
if( null != fm) temp.putAll( fm );
} else {
temp.put( k, v);
}
}
return temp;
}
/* bb_forums() */
public Map getForumsLoopElements( Map forums ) {
this.forumsLoop = BBLoop.start( forums, new BBWalkerBlank());
if( null != this.forumsLoop) {
//this.forumsLoop.preserve.add( "forum");
//this.forumsLoop.preserve.add("forum_id");
//this.forumsLoop.walker.dbFields.put("id", "forum_id");
//this.forumsLoop.walker.dbFields.put("parent", "forum_parent");
((BBWalkerBlank)this.forumsLoop.walker).setStartLvl("");
((BBWalkerBlank)this.forumsLoop.walker).setEndLvl("");
return this.forumsLoop.elements;
}
return null;
}
/* bb_forum() */
public int forumsLoopStep(){
if( null == this.forumsLoop) return 0;
if( this.forumsLoop.step()){
this.forum = (Forum) this.forumsLoop.elementValues.get( this.forumsLoop.getIndex());
} else {
//TODO: reinstate()
//this.forumsLoop.reinstate();
//this.forumsLoop = null;
return 0;
}
return this.forumsLoop.walker.depth;
}
public String getForumClass( String cssClass) {
List classes = this.forumsLoop.getClasses();
if( null != cssClass)
classes.add( 0, cssClass);
return StringUtils.join( classes, " ");
}
public String getAltClass( String key, String others) {
String css = "";
if( null == bbAlt.get(key)) bbAlt.put(key, -1);
bbAlt.put(key, bbAlt.get(key)+1);
if( null != others ^ 0 != (bbAlt.get(key) % 2))
css = " class='"+ (null != others? others: "alt")+ "'";
else if( null != others && 0 != (bbAlt.get(key) %2))
css = " class='"+ others + " alt'";
return css;
}
public boolean isForumIsCategory() {
return "1".equals( forum.getMetaValue("forum_is_category"));
}
public BBLoop getForumsLoop() {
return forumsLoop;
}
public Forum getForum() {
return forum;
}
}