/*-
 * Copyright (C) 2008 Erik Larsson
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.catacombae.io;

/**
 * A full read/write version of ReadableConcatenatedStream.
 * Note: Untested!
 *
 * @author <a href="http://hem.bredband.net/catacombae">Erik Larsson</a>
 */
public class ConcatenatedStream extends BasicConcatenatedStream<RandomAccessStream> implements RandomAccessStream {
    
    public ConcatenatedStream(RandomAccessStream firstPart, long startOffset, long length) {
        super(firstPart, startOffset, length);
    }

    public void write(byte[] data) throws RuntimeIOException {
        BasicWritable.defaultWrite(this, data);
    }

    public void write(byte[] data, int off, int len) throws RuntimeIOException {
        int bytesWritten = 0;

        // First: Look up the position represented by our virtual file pointer.
        long bytesToSkip = virtualFP;
        int requestedPartIndex = -1;
        for(Part p : parts) {
            ++requestedPartIndex;

            if(bytesToSkip > p.length) {
                bytesToSkip -= p.length;
            }
            else {
                break;
            }
        }
        if(requestedPartIndex == -1)
            throw new RuntimeIOException("Tried to write beyond end of file.");

        // Loop as long as we still have data to fill, and we still have parts to process.
        while(bytesWritten < len && requestedPartIndex < parts.size()) {
            Part requestedPart = parts.get(requestedPartIndex++);
            long bytesToSkipInPart = bytesToSkip;
            bytesToSkip = 0;

            int bytesLeftToWrite = len - bytesWritten;
            int bytesToWrite = (int) ((bytesLeftToWrite < requestedPart.length) ? bytesLeftToWrite : requestedPart.length);

            requestedPart.file.seek(bytesToSkipInPart);
            requestedPart.file.write(data, off + bytesWritten, bytesToWrite);
            
            bytesWritten += bytesToWrite;
        }

        if(bytesWritten < len)
            throw new RuntimeIOException("Could not write all data requested (wrote: " +
                    bytesWritten + " requested:" + len + ".");
        
        if(bytesWritten > len) // Debug check.
            throw new RuntimeException("Wrote more than I was supposed to (" + bytesWritten +
                    " / " + len + " bytes)! This can't happen.");
    }

    public void write(int data) throws RuntimeIOException {
        BasicWritable.defaultWrite(this, data);
    }
}
@@ -1622,18 +1622,17 @@
 Index = 
--1
+0
 ;%0A      
@@ -1659,43 +1659,8 @@
 ) %7B%0A
-            ++requestedPartIndex;%0A%0A
     
@@ -1682,17 +1682,17 @@
 sToSkip 
-%3E
+%3C
  p.lengt
@@ -1716,70 +1716,101 @@
     
-bytesToSkip -= p.length;%0A            %7D%0A            else %7B%0A
+/* The first byte of virtualFP is within this part. */%0A                break;%0A       
     
+ %7D%0A%0A
     
@@ -1817,36 +1817,74 @@
         
-break;%0A            %7D
+++requestedPartIndex;%0A            bytesToSkip -= p.length;
 %0A       
@@ -1886,16 +1886,17 @@
       %7D%0A
+%0A
         
@@ -1921,14 +1921,26 @@
 dex 
-== -1)
+%3E= parts.size()) %7B
 %0A   
@@ -2011,16 +2011,53 @@
  of 
-file.%22);
+%22 +%0A                    %22stream.%22);%0A        %7D
 %0A%0A  

Fix writing beyond bounds of stream.