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

package org.jboss.media.format.audio.mpeg;

import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;

import javax.emb.MediaException;

/**
 * An ID3 tag, used in MPEG audio files to store meta-data. 
 * See the <a href="http://www.id3.org">ID3 web site</a> for details.
 * 
 * @version <tt>$Revision 1.1 $</tt>
 * @author <a href="mailto:ogreen@users.sourceforge.net">Owen Green</a>
 */
class ID3Tag
{
   private int size = 0;
   private boolean unsynchronisation;
   private boolean extendedHeader;
   private boolean experimentalHeader;
   private boolean footerPresent;

   private byte versionMajor = 0;
   private byte versionMinor = 0;

   /**
    * Constructs a new ID3 tag extracted from the supplied <code>Media</code>
    * instance
    * @param mediaObject the <code>Media</code> instance to extract ID3 information from
    */
   public ID3Tag(InputStream content) throws MediaException, RemoteException
   {
      try
      {
         int offset = 3;

         //retrieve the size now, so we can pull the whole tag from the media object

         content.read(new byte[6]);

         byte[] tagSize = new byte[4];
         content.read(tagSize);
         size = convertSynchsafeInt(tagSize);

         //pull the whole thing out
         byte[] tagData = new byte[size];

         content.read(tagData);

         versionMajor = tagData[offset++];
         versionMinor = tagData[offset++];

         byte flags = tagData[offset++];

         unsynchronisation = (flags & 0x80) > 0;
         extendedHeader = (flags & 0x40) > 0;
         experimentalHeader = (flags & 0x20) > 0;
         footerPresent = (flags & 0x10) > 0;
      }
      catch (IOException e)
      {
         throw new MediaException(e);
      }
   }

   /**
    * Returns the size of the tag in bytes
    */
   public int getSize()
   {
      return size;
   }

   private int convertSynchsafeInt(byte[] data)
   {
      if (data.length < 4)
      {
         throw new IllegalArgumentException("Synchsafe integer must be 4 bytes long");
      }

      return convertSynchsafeInt(data[0], data[1], data[2], data[3]);
   }

   private int convertSynchsafeInt(byte msb, byte b3, byte b2, byte lsb)
   {
      return (msb << 23) + (b3 << 15) + (b2 << 7) + lsb;
   }
}