package org.muckebox.android.net;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.Queue;

import android.util.Log;

public class DownloadServerRunnable implements Runnable {
    private static final String LOG_TAG = "DownloadServer";
    private static final int PORT = 2342;
    
    private String mMimeType;

    private boolean mReady = false;
    
    private Queue<ByteBuffer> mQueue;
    
    public static String getUrl() {
        return "http://localhost:" + PORT + "/";
    }
    
    public DownloadServerRunnable(String mimeType) {
        mMimeType = mimeType;
        
        mQueue = new LinkedList<ByteBuffer>();
    }

    @Override
    public void run() {
        try {
            ServerSocket serverSocket = null;
            Socket socket = null;
            OutputStream os = null;
            
            Log.d(LOG_TAG, "Starting server on " + PORT);
            
            try {
                serverSocket = new ServerSocket(PORT);
                
                mReady = true;
                
                socket = serverSocket.accept();
                os = socket.getOutputStream();
                
                Log.d(LOG_TAG, "Got connection!");
            
                os.write(new String("HTTP/1.1 200 OK\n").getBytes());
                os.write(new String("Content-Type: " + mMimeType + "\n").getBytes());
                os.write(new String("Connection: close\n").getBytes());
                os.write(new String("\n").getBytes());
                
                boolean eosSeen = false;
                
                while (! eosSeen)
                {
                    while (mQueue.isEmpty()) {
                        synchronized (mQueue) {
                            mQueue.wait();
                        }
                    }
                    
                    synchronized (mQueue) {
                        ByteBuffer buf = mQueue.remove();
                        
                        if (buf == null)
                        {
                            eosSeen = true;
                            break;
                        }
                        
                        os.write(buf.array(), 0, buf.position());
                    }
                }
            } finally {
                if (os != null)
                    os.close();
                
                if (socket != null)
                    socket.close();
                
                if (serverSocket != null)
                    serverSocket.close();
            }
            
            Log.d(LOG_TAG, "Finished");
        } catch (InterruptedException e) {
            // should be ok?
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void feed(ByteBuffer buf) {
        synchronized (mQueue) {
            mQueue.add(buf);
            mQueue.notify();
        }
    }
    
    public boolean isReady() {
        return mReady;
    }
    
}

@@ -1388,16 +1388,18 @@
  200 OK%5C
+r%5C
 n%22).getB
@@ -1476,16 +1476,18 @@
 ype + %22%5C
+r%5C
 n%22).getB
@@ -1550,16 +1550,18 @@
 : close%5C
+r%5C
 n%22).getB
@@ -1606,16 +1606,101 @@
 String(%22
+Transfer-Encoding: chunked%5Cr%5Cn%22).getBytes());%0A                os.write(new String(%22%5Cr
 %5Cn%22).get
@@ -2229,32 +2229,135 @@
               %7B%0A
+                            os.write(new String(%220%5Cr%5Cn%5Cr%5Cn%22).getBytes());%0A                            %0A
                 
@@ -2376,32 +2376,61 @@
 eosSeen = true;%0A
+                            %0A
                 
@@ -2536,36 +2536,187 @@
 ite(
-buf.array(), 0, buf.position
+String.format(%22%25x%5Cr%5Cn%22, buf.position()).getBytes());%0A                        os.write(buf.array(), 0, buf.position());%0A                        os.write(new String(%22%5Cr%5Cn%22).getBytes
 ());

Use chunked encoding for streaming to media player.