package com.googlecode.mp4parser.authoring.tracks;

import com.coremedia.iso.boxes.*;
import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;
import com.googlecode.mp4parser.authoring.AbstractTrack;
import com.googlecode.mp4parser.authoring.TrackMetaData;
import com.googlecode.mp4parser.boxes.EC3SpecificBox;
import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: magnus
 * Date: 2012-03-14
 * Time: 10:39
 * To change this template use File | Settings | File Templates.
 */
public class EC3TrackImpl extends AbstractTrack {
    TrackMetaData trackMetaData = new TrackMetaData();
    SampleDescriptionBox sampleDescriptionBox;

    int samplerate;
    int bitrate;
    int frameSize;

    List<BitStreamInfo> entries = new LinkedList<BitStreamInfo>();

    private BufferedInputStream inputStream;
    private List<ByteBuffer> samples;
    List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();
    private String lang = "und";

    public EC3TrackImpl(InputStream fin, String lang) throws IOException {
        this.lang = lang;
        parse(fin);
    }

    public EC3TrackImpl(InputStream fin) throws IOException {
        parse(fin);
    }

    private void parse(InputStream fin) throws IOException {
        inputStream = new BufferedInputStream(fin);

        boolean done = false;
        inputStream.mark(10000);
        while (!done) {
            BitStreamInfo bsi = readVariables();
            if (bsi == null) {
                throw new IOException();
            }
            for (BitStreamInfo entry : entries) {
                if (bsi.strmtyp != 1 && entry.substreamid == bsi.substreamid) {
                    done = true;
                }
            }
            if (!done) {
                entries.add(bsi);
                long skipped = inputStream.skip(bsi.frameSize);
                assert skipped == bsi.frameSize;
            }
        }

        inputStream.reset();

        if (entries.size() == 0) {
            throw new IOException();
        }
        samplerate = entries.get(0).samplerate;

        sampleDescriptionBox = new SampleDescriptionBox();
        AudioSampleEntry audioSampleEntry = new AudioSampleEntry("ec-3");
        audioSampleEntry.setChannelCount(2);  // According to  ETSI TS 102 366 Annex F
        audioSampleEntry.setSampleRate(samplerate);
        audioSampleEntry.setDataReferenceIndex(1);
        audioSampleEntry.setSampleSize(16);

        EC3SpecificBox ec3 = new EC3SpecificBox();
        int[] deps = new int[entries.size()];
        int[] chan_locs = new int[entries.size()];
        for (BitStreamInfo bsi : entries) {
            if (bsi.strmtyp == 1) {
                deps[bsi.substreamid]++;
                chan_locs[bsi.substreamid] = ((bsi.chanmap >> 6) & 0x100) | ((bsi.chanmap >> 5) & 0xff);
            }
        }
        for (BitStreamInfo bsi : entries) {
            if (bsi.strmtyp != 1) {
                EC3SpecificBox.Entry e = new EC3SpecificBox.Entry();
                e.fscod = bsi.fscod;
                e.bsid = bsi.bsid;
                e.bsmod = bsi.bsmod;
                e.acmod = bsi.acmod;
                e.lfeon = bsi.lfeon;
                e.reserved = 0;
                e.num_dep_sub = deps[bsi.substreamid];
                e.chan_loc = chan_locs[bsi.substreamid];
                e.reserved2 = 0;
                ec3.addEntry(e);
            }
            bitrate += bsi.bitrate;
            frameSize += bsi.frameSize;
        }

        ec3.setDataRate(bitrate / 1000);
        audioSampleEntry.addBox(ec3);
        sampleDescriptionBox.addBox(audioSampleEntry);

        trackMetaData.setCreationTime(new Date());
        trackMetaData.setModificationTime(new Date());
        trackMetaData.setLanguage(lang);
        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale

        samples = new LinkedList<ByteBuffer>();
        if (!readSamples()) {
            throw new IOException();
        }
    }


    public List<ByteBuffer> getSamples() {

        return samples;
    }

    public SampleDescriptionBox getSampleDescriptionBox() {
        return sampleDescriptionBox;
    }

    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
        return stts;
    }

    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
        return null;
    }

    public long[] getSyncSamples() {
        return null;
    }

    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
        return null;
    }

    public TrackMetaData getTrackMetaData() {
        return trackMetaData;
    }

    public String getHandler() {
        return "soun";
    }

    public AbstractMediaHeaderBox getMediaHeaderBox() {
        return new SoundMediaHeaderBox();
    }

    public SubSampleInformationBox getSubsampleInformationBox() {
        return null;
    }

    private BitStreamInfo readVariables() throws IOException {
        byte[] data = new byte[200];
        inputStream.mark(200);
        if (200 != inputStream.read(data, 0, 200)) {
            return null;
        }
        inputStream.reset(); // Rewind
        ByteBuffer bb = ByteBuffer.wrap(data);
        BitReaderBuffer brb = new BitReaderBuffer(bb);
        int syncword = brb.readBits(16);
        if (syncword != 0xb77) {
            return null;
        }

        BitStreamInfo entry = new BitStreamInfo();

        entry.strmtyp = brb.readBits(2);
        entry.substreamid = brb.readBits(3);
        int frmsiz = brb.readBits(11);
        entry.frameSize = 2 * (frmsiz + 1);

        entry.fscod = brb.readBits(2);
        int fscod2 = -1;
        int numblkscod;
        if (entry.fscod == 3) {
            fscod2 = brb.readBits(2);
            numblkscod = 3;
        } else {
            numblkscod = brb.readBits(2);
        }
        int numberOfBlocksPerSyncFrame = 0;
        switch (numblkscod) {
            case 0:
                numberOfBlocksPerSyncFrame = 1;
                break;

            case 1:
                numberOfBlocksPerSyncFrame = 2;
                break;

            case 2:
                numberOfBlocksPerSyncFrame = 3;
                break;

            case 3:
                numberOfBlocksPerSyncFrame = 6;
                break;

        }
        entry.frameSize *= (6 / numberOfBlocksPerSyncFrame);

        entry.acmod = brb.readBits(3);
        entry.lfeon = brb.readBits(1);
        entry.bsid = brb.readBits(5);
        brb.readBits(5);
        if (1 == brb.readBits(1)) {
            brb.readBits(8); // compr
        }
        if (0 == entry.acmod) {
            brb.readBits(5);
            if (1 == brb.readBits(1)) {
                brb.readBits(8);
            }
        }
        if (1 == entry.strmtyp) {
            if (1 == brb.readBits(1)) {
                entry.chanmap = brb.readBits(16);
            }
        }
        if (1 == brb.readBits(1)) {     // mixing metadata
            if (entry.acmod > 2) {
                brb.readBits(2);
            }
            if (1 == (entry.acmod & 1) && entry.acmod > 2) {
                brb.readBits(3);
                brb.readBits(3);
            }
            if (0 < (entry.acmod & 4)) {
                brb.readBits(3);
                brb.readBits(3);
            }
            if (1 == entry.lfeon) {
                if (1 == brb.readBits(1)) {
                    brb.readBits(5);
                }
            }
            if (0 == entry.strmtyp) {
                if (1 == brb.readBits(1)) {
                    brb.readBits(6);
                }
                if (0 == entry.acmod) {
                    if (1 == brb.readBits(1)) {
                        brb.readBits(6);
                    }
                }
                if (1 == brb.readBits(1)) {
                    brb.readBits(6);
                }
                int mixdef = brb.readBits(2);
                if (1 == mixdef) {
                    brb.readBits(5);
                } else if (2 == mixdef) {
                    brb.readBits(12);
                } else if (3 == mixdef) {
                    int mixdeflen = brb.readBits(5);
                    if (1 == brb.readBits(1)) {
                        brb.readBits(5);
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            if (1 == brb.readBits(1)) {
                                brb.readBits(4);
                            }
                            if (1 == brb.readBits(1)) {
                                brb.readBits(4);
                            }
                        }
                    }
                    if (1 == brb.readBits(1)) {
                        brb.readBits(5);
                        if (1 == brb.readBits(1)) {
                            brb.readBits(7);
                            if (1 == brb.readBits(1)) {
                                brb.readBits(8);
                            }
                        }
                    }
                    for (int i = 0; i < (mixdeflen + 2); i++) {
                        brb.readBits(8);
                    }
                    brb.byteSync();
                }
                if (entry.acmod < 2) {
                    if (1 == brb.readBits(1)) {
                        brb.readBits(14);
                    }
                    if (0 == entry.acmod) {
                        if (1 == brb.readBits(1)) {
                            brb.readBits(14);
                        }
                    }
                    if (1 == brb.readBits(1)) {
                        if (numblkscod == 0) {
                            brb.readBits(5);
                        } else {
                            for (int i = 0; i < numberOfBlocksPerSyncFrame; i++) {
                                if (1 == brb.readBits(1)) {
                                    brb.readBits(5);
                                }
                            }
                        }

                    }
                }
            }
        }
        if (1 == brb.readBits(1)) { // infomdate
            entry.bsmod = brb.readBits(3);
        }

        switch (entry.fscod) {
            case 0:
                entry.samplerate = 48000;
                break;

            case 1:
                entry.samplerate = 44100;
                break;

            case 2:
                entry.samplerate = 32000;
                break;

            case 3: {
                switch (fscod2) {
                    case 0:
                        entry.samplerate = 24000;
                        break;

                    case 1:
                        entry.samplerate = 22050;
                        break;

                    case 2:
                        entry.samplerate = 16000;
                        break;

                    case 3:
                        entry.samplerate = 0;
                        break;
                }
                break;
            }

        }
        if (entry.samplerate == 0) {
            return null;
        }

        entry.bitrate = (int) (((double) entry.samplerate) / 1536.0 * entry.frameSize * 8);

        return entry;
    }

    private boolean readSamples() throws IOException {
        int read = frameSize;
        boolean ret = false;
        while (frameSize == read) {
            ret = true;
            byte[] data = new byte[frameSize];
            read = inputStream.read(data);
            if (read == frameSize) {
                samples.add(ByteBuffer.wrap(data));
                stts.add(new TimeToSampleBox.Entry(1, 1536));
            }
        }
        return ret;
    }

    public static class BitStreamInfo extends EC3SpecificBox.Entry {
        public int frameSize;
        public int substreamid;
        public int bitrate;
        public int samplerate;
        public int strmtyp;
        public int chanmap;

        @Override
        public String toString() {
            return "BitStreamInfo{" +
                    "frameSize=" + frameSize +
                    ", substreamid=" + substreamid +
                    ", bitrate=" + bitrate +
                    ", samplerate=" + samplerate +
                    ", strmtyp=" + strmtyp +
                    ", chanmap=" + chanmap +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "EC3TrackImpl{" +
                "bitrate=" + bitrate +
                ", samplerate=" + samplerate +
                ", entries=" + entries +
                '}';
    }
}
