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

package org.jboss.media;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;

import javax.emb.ContentAccessException;
import javax.emb.Media;
import javax.emb.MediaException;
import javax.emb.MediaFormat;
import javax.emb.MediaFormatRegistry;
import javax.emb.MediaHeader;

import org.jboss.media.util.ByteBufferUtils;

/**
 * An implementation of the <code>Media</code> interface using Java2 1.4's new I/O API.
 *
 * This class is not in use yet...
 *
 * @version <tt>$Revision: 1.2 $</tt>
 * @author <a href="mailto:ricardoarguello@users.sourceforge.net">Ricardo Argüello</a>
 */
public class NIOMediaBean implements Media
{
   private String name;
   private String mimeType;

   // Check if it's direct? (shouldn't be)
   private ByteBuffer byteBuffer;

   private long size;

   public NIOMediaBean(InputStream contentStream, String mimeType, String name)
      throws MediaException
   {
      if (contentStream == null || name == null)
      {
         throw new NullPointerException();
      }

      if (mimeType == null)
      {
         mimeType = getFormat().getDefaultMimeType();
      }
      else
      {
         this.mimeType = mimeType;
      }

      this.name = name;

      ReadableByteChannel byteChannel = Channels.newChannel(contentStream);

      try
      {
         this.size = byteChannel.read(byteBuffer); // uh?
      }
      catch (IOException e)
      {
         throw new ContentAccessException(e.getMessage());
      }
      finally
      {
         try
         {
            contentStream.close();
         }
         catch (IOException exception)
         {
         }
      }
   }

   public NIOMediaBean(File mediaFile, String mimeType) throws MediaException
   {
      try
      {
         // Hummmm: FileChannel fileChannel = new RandomAccessFile(mediaFile, "r").getChannel();
         FileChannel fileChannel = new FileInputStream(mediaFile).getChannel();
         this.size = fileChannel.size();
         this.byteBuffer =
            fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int) size);
      }
      catch (IOException e)
      {
         throw new ContentAccessException(e.getMessage());
      }
   }

   public byte[] getContent() throws MediaException
   {
      return byteBuffer.array();
   }

   public int readContent(long position, byte[] buffer) throws MediaException
   {
      return readContent(position, buffer, 0, buffer.length);
   }

   public int readContent(long position, byte[] buffer, int offset, int length)
      throws MediaException
   {
      byteBuffer.get(buffer, offset, length);

      // This is not correct, find a better way!
      return buffer.length;
   }

   public MediaFormat getFormat() throws MediaException
   {
      String fileExtension = getFileExtension(name);

      if (fileExtension != null)
      {
         return MediaFormatRegistry.SINGLETON.lookup(fileExtension);
      }
      else
      {
         return null;
      }
   }

   public MediaHeader getHeader() throws MediaException
   {
      InputStream content = new ByteArrayInputStream(this.getContent());
      return getFormat().extractHeader(content);
   }

   public String getMimeType() throws MediaException
   {
      return mimeType;
   }

   public String getName() throws MediaException
   {
      return name;
   }

   public long getSize() throws MediaException
   {
      return size;
   }

   public Media getProxy() throws MediaException
   {
      InputStream content = new ByteArrayInputStream(this.getContent());
      return this.getFormat().extractProxy(content);
   }

   // Private ------------------------------------------
   private static String getFileName(String fileName)
   {
      int lastDotPosition = fileName.lastIndexOf('.');

      if (lastDotPosition == -1)
      {
         return fileName;
      }
      else
      {
         return fileName.substring(0, lastDotPosition);
      }
   }

   private static String getFileExtension(String fileName)
   {
      int lastDotPosition = fileName.lastIndexOf('.');

      if (lastDotPosition == -1)
      {
         return null;
      }
      else
      {
         return fileName.substring(lastDotPosition + 1);
      }
   }

   private InputStream getContentStream() throws MediaException
   {
      return ByteBufferUtils.newInputStream(byteBuffer);
   }
}