/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.menus;

import java.util.*;
import org.w3c.dom.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.config.RootConfig;

public class CommunityMenuFactory
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private List entries;
  private Map map_symbol;

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  public CommunityMenuFactory(Element comm_sect, RootConfig rconf) throws ConfigException
  {
    if (comm_sect!=null)
    { // look for community services
      NodeList nl = comm_sect.getChildNodes();
      ArrayList tmp_entries = new ArrayList(nl.getLength());
      HashMap tmp_map = new HashMap();
      for (int i=0; i<nl.getLength(); i++)
      { // get each node and see if it's a service node
	Node n = nl.item(i);
	if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("service")))
	{ // create a template LeftMenuEntry and add it
	  CommunityMenuEntry ent = new CommunityMenuEntry((Element)n,rconf);
	  tmp_entries.add(ent);
	  tmp_map.put(ent.getSymbol(),ent);

	} // end if

      } // end for

      if (tmp_entries.isEmpty())
      { // dummy it all out
	entries = Collections.EMPTY_LIST;
	map_symbol = Collections.EMPTY_MAP;

      } // end if
      else
      { // sort the list by sequence before we save it
	if (tmp_entries.size()>1)
	  Collections.sort(tmp_entries);
	tmp_entries.trimToSize();
	entries = Collections.unmodifiableList(tmp_entries);
	map_symbol = Collections.unmodifiableMap(tmp_map);

      } // end else

    } // end if
    else
    { // no communty services - initialize to null
      entries = Collections.EMPTY_LIST;
      map_symbol = Collections.EMPTY_MAP;

    } // end else

  } // end constructor

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  public final CommunityMenu createMenu(CommunityContext comm)
  {
    List items;
    if (entries.size()>0)
    { // Get the community services and stash the symbols in a set.
      HashSet defined = new HashSet();
      Iterator it = comm.getServices().iterator();
      while (it.hasNext())
      { // add each symbol to the set
	ServiceToken token = (ServiceToken)(it.next());
	defined.add(token.getSymbol());
	
      } // end while

      // Create the map used to replace the variables in the menu items.
      HashMap vars = new HashMap();
      vars.put("cid",String.valueOf(comm.getCommunityID()));

      // Run through the list of entries (sorted by sequence) and add them.
      ArrayList tmp_items = new ArrayList(defined.size());
      it = entries.iterator();
      while (it.hasNext())
      { // get this entry and see if there's a match in the set
	CommunityMenuEntry ntry = (CommunityMenuEntry)(it.next());
	if (defined.contains(ntry.getSymbol()))
	  tmp_items.add(ntry.resolveItem(vars));

      } // end while

      if (tmp_items.isEmpty())  // dummy out the list
	items = Collections.EMPTY_LIST;
      else
      { // make the list unmodifiable
	tmp_items.trimToSize();
	items = Collections.unmodifiableList(tmp_items);

      } // end else

    } // end if
    else // no defined services - short-circuit the whole business
      items = Collections.EMPTY_LIST;

    // the constructor will handle the rest of the initialization
    return new CommunityMenu(comm,items);

  } // end createMenu

  public final String getDefaultServletAddress(RequestOutput out, CommunityContext comm)
  {
    ServiceToken token = comm.getDefaultService();
    if (token==null)
      return null;
    CommunityMenuEntry ent = (CommunityMenuEntry)(map_symbol.get(token.getSymbol()));
    if (ent==null)
      return null;

    // Create the map used to replace the variables in the servlet address.
    HashMap vars = new HashMap();
    vars.put("cid",String.valueOf(comm.getCommunityID()));

    return ent.getServletAddress(out,vars);

  } // end getDefaultServletAddress

  public final String getDefaultServletAddress(RequestInput inp, CommunityContext comm)
  {
    ServiceToken token = comm.getDefaultService();
    if (token==null)
      return null;
    CommunityMenuEntry ent = (CommunityMenuEntry)(map_symbol.get(token.getSymbol()));
    if (ent==null)
      return null;

    // Create the map used to replace the variables in the servlet address.
    HashMap vars = new HashMap();
    vars.put("cid",String.valueOf(comm.getCommunityID()));

    return ent.getServletAddress(inp,vars);

  } // end getDefaultServletAddress

} // end class CommunityMenuFactory
