/*
 * 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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.gagravarr.ogg.IOUtils;


/**
 * This comes before the audio data.
 * Made up of a series of:
 *  1 byte type
 *  3 byte length
 *  <data>
 */
public abstract class FlacMetadataBlock extends FlacFrame {
   public static final byte STREAMINFO = 0;
   public static final byte PADDING = 1;
   public static final byte APPLICATION = 2;
   public static final byte SEEKTABLE = 3;
   public static final byte VORBIS_COMMENT = 4;
   public static final byte CUESHEET = 5;
   public static final byte PICTURE = 6;
   // 7-126 : reserved
   // 127 : invalid, to avoid confusion with a frame sync code
   public static final int MASK_BLOCKTYPE = 0x7F; // TODO: Java 7 use 0b01111111
   public static final int MASK_LASTBLOCK = 0x80; // TODO: Java 7 use 0b10000000
	
   private byte type;
   
   public static FlacMetadataBlock create(InputStream inp) throws IOException {
      int typeI = inp.read();
      if(typeI == -1) {
         throw new IllegalArgumentException();
      }
      byte type = IOUtils.fromInt(typeI);
      byte[] l = new byte[3];
      IOUtils.readFully(inp, l);
      int length = (int)IOUtils.getInt3BE(l);

      byte[] data = new byte[length];
      IOUtils.readFully(inp, data);

      // Grab the type, whether the last block or not
      int  blockType = type & MASK_BLOCKTYPE;

      switch(blockType) {
         case STREAMINFO:
            return new FlacInfo(data, 0);
         case VORBIS_COMMENT:
            return new FlacTags.FlacTagsAsMetadata(type, data);
         default:
            return new FlacUnhandledMetadataBlock(type, data);
      }
   }

	protected FlacMetadataBlock(byte type) {
		this.type = type;
	}
	
	public int getType() {
		return type & MASK_BLOCKTYPE;
	}

	public boolean isLastMetadataBlock() {
	    // Top bit of the type is the flag for this
        return (type & MASK_LASTBLOCK) != 0;
   }
	
   public byte[] getData() {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      
      try {
         // Type goes first
         baos.write(type);
         // Pad length, will do later
         baos.write(new byte[3]);
         
         // Do the main data
         write(baos);
      } catch(IOException e) {
         // Shouldn't ever happen!
         throw new RuntimeException(e);
      }
      
      // Fix the length
      byte[] data = baos.toByteArray();
      IOUtils.putInt3BE(data, 1, data.length);
      
      // All done
      return data;
   }
	
	protected abstract void write(OutputStream out) throws IOException;
}

@@ -1473,17 +1473,16 @@
 0000000%0A
-%09
 %0A   priv
@@ -1496,19 +1496,16 @@
 e type;%0A
-   
 %0A   publ
@@ -2297,17 +2297,19 @@
 %7D%0A   %7D%0A%0A
-%09
+   
 protecte
@@ -2341,18 +2341,23 @@
 type) %7B%0A
-%09%09
+       
 this.typ
@@ -2370,14 +2370,17 @@
 pe;%0A
-%09%7D%0A%09%0A%09
+   %7D%0A%0A   
 publ
@@ -2402,10 +2402,15 @@
 ) %7B%0A
-%09%09
+       
 retu
@@ -2439,13 +2439,17 @@
 PE;%0A
-%09%7D%0A%0A%09
+   %7D%0A%0A   
 publ
@@ -2487,13 +2487,15 @@
 ) %7B%0A
-%09
+  
     
+ 
 // T
@@ -2537,25 +2537,24 @@
 this%0A       
- 
 return (type
@@ -2583,17 +2583,16 @@
 0;%0A   %7D%0A
-%09
 %0A   publ
@@ -2619,16 +2619,17 @@
 %7B%0A      
+ 
 ByteArra
@@ -2678,28 +2678,23 @@
 ream();%0A
+%0A
       
-%0A     
  try %7B%0A 
@@ -2697,24 +2697,26 @@
  %7B%0A         
+ 
+ 
 // Type goes
@@ -2722,16 +2722,18 @@
 s first%0A
+  
         
@@ -2760,16 +2760,18 @@
         
+  
 // Pad l
@@ -2792,32 +2792,34 @@
  later%0A         
+ 
+ 
 baos.write(new b
@@ -2831,18 +2831,11 @@
 %5D);%0A
-       
+%0A
   
-%0A
     
@@ -2859,16 +2859,18 @@
 in data%0A
+  
         
@@ -2889,16 +2889,17 @@
 ;%0A      
+ 
 %7D catch(
@@ -2911,24 +2911,26 @@
 eption e) %7B%0A
+  
          // 
@@ -2953,32 +2953,34 @@
 appen!%0A         
+  
 throw new Runtim
@@ -2994,24 +2994,25 @@
 ion(e);%0A
+ 
       %7D%0A
       %0A 
@@ -3003,29 +3003,24 @@
       %7D%0A
-    
+%0A
   
-%0A
      
- 
 // Fix t
@@ -3029,16 +3029,17 @@
  length%0A
+ 
       by
@@ -3066,24 +3066,25 @@
 yteArray();%0A
+ 
       IOUtil
@@ -3122,19 +3122,14 @@
 h);%0A
- 
+%0A
      
-%0A    
   //
@@ -3138,16 +3138,17 @@
 ll done%0A
+ 
       re
@@ -3167,11 +3167,12 @@
   %7D%0A
-%09%0A%09
+%0A   
 prot

Fix whitespace