/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license. See terms of license at gnu.org.
 */

package javax.emb;

import java.io.InputStream;
import java.net.URL;

/**
 * This class offers a generic implementation of the {@link MediaFormat}
 * interface for use with all kinds of embedded media formats. Note that this
 * class should not be used to represent non-embedded media formats, as it does
 * not handle parent/child relationships. By registering instances of this
 * class with the {@link MediaFormatRegistry}described in the followup
 * section, various media formats can be supported in case no format specific
 * support is available.
 * 
 * <p>The public constant <code>DEFAULT_PROXY</code> contains an image that
 * can be used as a default proxy for all kinds of media formats or in case the
 * generation of a proxy fails for whatever reason.
 * 
 * @version <tt>$Revision: 1.4 $</tt>
 * @author <a href="mailto:ricardoarguello@users.sourceforge.net">Ricardo
 *         Argüello</a>
 */
public class GenericMediaFormat implements MediaFormat
{
   // TODO: Implement a default proxy
   public static final Media DEFAULT_PROXY = null;

   /**
    * Returns the content of the given media segment array's first element, or
    * an empty byte array if no element is passed.
    * 
    * @param mediaLocation the intended location of the media to be assembled.
    * @param mediaSegments the segments that are to be assembled.
    * @return the assembled content.
    * @throws javax.emb.FormatSyntaxException if the given media segment array
    *         contains more than one element, or if an element is passed that
    *         contains a child link that is not <code>null</code>.
    * @throws java.lang.NullPointerException if the given segment array is
    *         <code>null</code>.
    * @throws javax.emb.ContentTooLargeException if the assembled content is
    *         larger than the maximum Java array size of 2 GB.
    */
   public byte[] assembleContent(
      URL mediaLocation,
      MediaSegment[] mediaSegments)
      throws MediaException
   {
      if (mediaSegments == null)
      {
         throw new NullPointerException();
      }

      if (mediaSegments.length == 0)
      {
         return new byte[0];
      }

      if (mediaSegments.length > 1)
      {
         throw new FormatSyntaxException("Media segment array contains more than one element.");
      }

      MediaSegment mediaSegment = mediaSegments[0];

      if (mediaSegment.getChildLocation() != null)
      {
         throw new FormatSyntaxException("Element passed contains a child link that is not null.");
      }

      return mediaSegment.getContent();
   }

   /**
    * Disassembles the given media content. As embedded media doesn – t contain
    * any links and therefore consists of a single media segment, this generic
    * implementation returns a one-element array of media segments, with a
    * segment element composed of <code>null</code> as child location and the
    * given media content as content.
    * 
    * @param mediaLocation the location of the media to be disassembled.
    * @param mediaContent the content to be disassembled.
    * @return the segments.
    * @throws java.lang.NullPointerException if the content passed is <code>null</code>.
    */
   public MediaSegment[] disassembleContent(
      URL mediaLocation,
      byte[] mediaContent)
      throws MediaException
   {
      if (mediaContent == null)
      {
         throw new NullPointerException();
      }

      MediaSegment mediaSegment = new MediaSegment();
      mediaSegment.setContent(mediaContent);

      return new MediaSegment[] { mediaSegment };
   }

   /**
    * Returns an instance of class GenericMediaHeader, as this class cannot
    * make any assumptions about header fields.
    * 
    * @param content the content stream to extract the header from.
    * @return the media header.
    * @throws java.lang.NullPointerException if the value passed is <code>null</code>.
    */
   public MediaHeader extractHeader(InputStream mediaContent)
      throws MediaException
   {
      if (mediaContent == null)
      {
         throw new NullPointerException();
      }

      return new GenericMediaHeader();
   }

   /**
    * Returns a default image that is suitable to represent all kinds of
    * content.
    * 
    * @param mediaContent the media content.
    * @return the proxy.
    * @throws javax.emb.MediaException if proxy can't be generated.
    */
   public Media extractProxy(InputStream mediaContent) throws MediaException
   {
      // TODO: Return a generic surrogate image, use a static byte array.
      return null;
   }

   /**
    * Returns <code>Media.MIME_TYPE_UNKNOWN</code>, as this class cannot
    * make any assumptions about mime types.
    * 
    * @return <code>Media.MIME_TYPE_UNKNOWN</code>.
    */
   public String getDefaultMimeType()
   {
      return Media.MIME_TYPE_UNKNOWN;
   }

   /**
    * Returns <code>true</code>, as this class assumes media to be embedded.
    * 
    * @return <code>true</code>.
    */
   public boolean isEmbedded()
   {
      return true;
   }

   /**
    * Returns <code>false</code>, as this class cannot make any assumptions
    * about media to be streamable or not.
    * 
    * @return <code>false</code>.
    */
   public boolean isStreamingDesirable()
   {
      return false;
   }
}