/*
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gagravarr.flac;

import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.gagravarr.ogg.IOUtils;
import org.gagravarr.ogg.OggFile;

/**
 * This wrapper lets you work with FLAC files,
 *  whether they're Ogg or Native framed.
 */
public abstract class FlacFile implements Closeable {
    protected FlacInfo info;
    protected FlacTags tags;
    protected List<FlacMetadataBlock> otherMetadata;

    /**
     * Opens the given file for reading
     */
    public static FlacFile open(File f) throws IOException, FileNotFoundException {
        // Open, in a way that we can skip backwards a few bytes
        InputStream inp = new BufferedInputStream(new FileInputStream(f), 8);
        FlacFile file = open(inp);
        inp.close();
        return file;
    }
   /**
    * Opens the given file for reading.
    * @param inp The InputStrem to read from, which must support mark/reset
    */
   public static FlacFile open(InputStream inp) throws IOException, FileNotFoundException {
      inp.mark(4);
      byte[] header = new byte[4];
      IOUtils.readFully(inp, header);
      inp.reset();
      
      if(header[0] == (byte)'O' && header[1] == (byte)'g' &&
         header[2] == (byte)'g' && header[3] == (byte)'S') {
         return new FlacOggFile(new OggFile(inp));
      }
      if(header[0] == (byte)'f' && header[1] == (byte)'L' &&
         header[2] == (byte)'a' && header[3] == (byte)'C') {
         return new FlacNativeFile(inp);
      }
      throw new IllegalArgumentException("File type not recognised");
   }
	/**
	 * Opens the given file for reading
	 */
	public static FlacFile open(OggFile ogg) throws IOException {
		return new FlacOggFile(ogg);
	}
	
	public abstract FlacAudioFrame getNextAudioPacket() throws IOException;
	
	/**
	 * Skips the audio data to the next packet with a granule
	 *  of at least the given granule position.
	 * Note that skipping backwards is not currently supported!
	 */
	public abstract void skipToGranule(long granulePosition) throws IOException;
	
	public FlacInfo getInfo() {
		return info;
	}
	public FlacTags getTags() {
		return tags;
	}

	/**
	 * In Reading mode, will close the underlying ogg/flac
	 *  file and free its resources.
	 * In Writing mode, will write out the Info and 
	 *  Comments objects, and then the audio data.
	 */
	public abstract void close() throws IOException;
}

@@ -2282,22 +2282,26 @@
 );%0A   %7D%0A
-%09
+   
 /**%0A
-%09
+   
  * Opens
@@ -2328,22 +2328,26 @@
 reading%0A
-%09
+   
  */%0A
-%09
+   
 public s
@@ -2400,18 +2400,23 @@
 ption %7B%0A
-%09%09
+       
 return n
@@ -2440,14 +2440,17 @@
 g);%0A
-%09%7D%0A%09%0A%09
+   %7D%0A%0A   
 publ
@@ -2521,16 +2521,19 @@
 on;%0A
-%09%0A%09
+%0A   
 /**%0A
-%09
+   
  * S
@@ -2586,17 +2586,19 @@
 granule%0A
-%09
+   
  *  of a
@@ -2633,17 +2633,19 @@
 sition.%0A
-%09
+   
  * Note 
@@ -2696,22 +2696,26 @@
 ported!%0A
-%09
+   
  */%0A
-%09
+   
 public a
@@ -2787,11 +2787,12 @@
 on;%0A
-%09%0A%09
+%0A   
 publ
@@ -2811,26 +2811,31 @@
 getInfo() %7B%0A
-%09%09
+       
 return info;
@@ -2839,12 +2839,16 @@
 fo;%0A
-%09%7D%0A%09
+   %7D%0A   
 publ
@@ -2875,10 +2875,15 @@
 ) %7B%0A
-%09%09
+       
 retu
@@ -2895,18 +2895,24 @@
 gs;%0A
-%09%7D%0A%0A%09
+   %7D%0A%0A   
 /**%0A
-%09
+   
  * I
@@ -2962,17 +2962,19 @@
 gg/flac%0A
-%09
+   
  *  file
@@ -2998,17 +2998,19 @@
 ources.%0A
-%09
+   
  * In Wr
@@ -3050,17 +3050,19 @@
 fo and %0A
-%09
+   
  *  Comm
@@ -3104,14 +3104,18 @@
 ta.%0A
-%09
+   
  */%0A
-%09
+   
 publ

Reformat indents