/*
 * 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@ricochet.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.core.impl;

import java.io.*;
import java.text.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;

class ConferencingExporter
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Logger logger = Logger.getLogger(ConferencingExporter.class);

  private static final DateFormat s_datefmt;

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private StringWriter m_buffer = null;
  private PrintWriter m_wr = null;
  private Set m_include = null;

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

  ConferencingExporter()
  { // do nothing
  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal operations
   *--------------------------------------------------------------------------------
   */

  private void visit(TopicMessageUserContextImpl msg) throws DataException, AccessError, IOException
  {
    if (logger.isDebugEnabled())
      logger.debug("exporting post #" + msg.getPostNumber());

    m_wr.write("<post id=\"");
    m_wr.print(msg.getPostID());
    m_wr.write("\" parent=\"");
    m_wr.print(msg.getParentPostID());
    m_wr.write("\" index=\"");
    m_wr.print(msg.getPostNumber());
    m_wr.write("\" lines=\"");
    m_wr.print(msg.getNumLines());
    m_wr.write("\" author=\"");
    m_wr.write(msg.getCreatorName());
    m_wr.write("\" date=\"");
    m_wr.write(s_datefmt.format(msg.getPostDate()));
    m_wr.write("\" hidden=\"");
    m_wr.write(msg.isHidden() ? "true" : "false");
    m_wr.write("\">\n");
    if (msg.isScribbled())
    { // write out the scribble information
      m_wr.write("<scribbled by=\"");
      m_wr.write(msg.getScribblingUser());
      m_wr.write("\" date=\"");
      m_wr.write(s_datefmt.format(msg.getScribbleDate()));
      m_wr.write("\"/>\n");

    } // end if

    m_wr.write("<pseud><![CDATA[");
    m_wr.write(msg.getPseud());
    m_wr.write("]]></pseud>\n<text><![CDATA[");
    m_wr.write(msg.getBodyText());
    m_wr.write("]]></text>\n");

    if (msg.hasAttachment())
    { // write out the attachment information
      if (logger.isDebugEnabled())
	logger.debug("exporting attachment for post #" + msg.getPostNumber());

      m_wr.write("<attachment length=\"");
      m_wr.print(msg.getAttachmentLength());
      m_wr.write("\" type=\"");
      m_wr.write(msg.getAttachmentType());
      m_wr.write("\" filename=\"");
      m_wr.write(msg.getAttachmentFilename());
      m_wr.write("\">");
      Reader r = null;
      try
      { // copy the attachment data into the output
	r = new BufferedReader(new InputStreamReader(new Base64EncodeInputStream(msg.getAttachmentData()),
						     "US-ASCII"));
	IOUtil.copy(r,m_wr);

      } // end try
      catch (UnsupportedEncodingException e)
      { // whoops!
	throw new InternalStateError("Encoding not supported?");

      } // end catch
      catch (IOException e)
      { // what happened here?
	logger.error("I/O exception",e);
	throw e;

      } // end catch
      finally
      { // close down our reader when we're done
	IOUtil.shutdown(r);

      } // end finally

      m_wr.write("</attachment>\n");

    } // end if

    m_wr.write("</post>\n");

  } // end visit

  private void visit(TopicUserContextImpl topic) throws DataException, AccessError, IOException
  {
    if ((m_include!=null) && !(m_include.contains(new Integer(topic.getTopicNumber()))))
      return;  // skip this topic

    if (logger.isDebugEnabled())
      logger.debug("exporting topic \"" + topic.getName() + "\"");

    // write the main topic information
    m_wr.write("<topic index=\"");
    m_wr.print(topic.getTopicNumber());
    m_wr.write("\" frozen=\"");
    m_wr.write(topic.isFrozen() ? "true" : "false");
    m_wr.write("\" archived=\"");
    m_wr.write(topic.isArchived() ? "true" : "false");
    m_wr.write("\">\n<topicname><![CDATA[");
    m_wr.write(topic.getName());
    m_wr.write("]]></topicname>\n");
    
    // get the posts and write them out
    List l = topic.getMessages(0,topic.getTopMessage());
    for (Iterator it=l.iterator(); it.hasNext(); )
      visit((TopicMessageUserContextImpl)(it.next()));

    // done with the topic
    m_wr.write("</topic>\n");

  } // end visit

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

  void setTopics(Set s)
  {
    m_include = s;

  } // end setTopics

  String exportConference(ConferenceUserContextImpl conf) throws DataException, AccessError, IOException
  {
    if (logger.isDebugEnabled())
      logger.debug("exporting conference \"" + conf.getName() + "\"");
    m_buffer = new StringWriter();
    m_wr = new PrintWriter(m_buffer);
    m_wr.write("<?xml version=\"1.0\"?>\n<vcif>\n");

    List l = conf.getTopicList(ConferenceContext.GET_ALL,ConferenceContext.SORT_NUMBER,true);
    for (Iterator it=l.iterator(); it.hasNext(); )
      visit((TopicUserContextImpl)(it.next()));

    m_wr.write("</vcif>\n");
    m_wr.flush();

    // Return the finished buffer.
    String rc = m_buffer.toString();
    m_wr.close();
    m_wr = null;
    m_buffer = null;
    return rc;

  } // end exportConference

  /*--------------------------------------------------------------------------------
   * Static initializer
   *--------------------------------------------------------------------------------
   */

  static
  { // create an ISO 8601 date formatter
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
    df.setTimeZone(new SimpleTimeZone(0,"UTC"));
    s_datefmt = df;

  } // end static initializer

} // end class ConferencingExporter
