/**********
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 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

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
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A source that consists of multiple byte-stream files, read sequentially.
// (The input is an array of file names, with a terminating 'file name' of NULL.) 
// Implementation

#include "ByteStreamMultiFileSource.hh"

ByteStreamMultiFileSource
::ByteStreamMultiFileSource(UsageEnvironment& env, char const** fileNameArray,
			    unsigned preferredFrameSize, unsigned playTimePerFrame)
  : FramedSource(env),
    fPreferredFrameSize(preferredFrameSize), fPlayTimePerFrame(playTimePerFrame),
    fCurrentlyReadSourceNumber(0), fHaveStartedNewFile(False) {
    // Begin by counting the number of sources (by looking for a terminating 'file name' of NULL):
    for (fNumSources = 0; ; ++fNumSources) {
      if (fileNameArray[fNumSources] == NULL) break;
    }

    // Next, copy the source file names into our own array:
    fFileNameArray = new char const*[fNumSources];
    if (fFileNameArray == NULL) return;
    unsigned i;
    for (i = 0; i < fNumSources; ++i) {
      fFileNameArray[i] = strDup(fileNameArray[i]);
    }

    // Next, set up our array of component ByteStreamFileSources
    // Don't actually create these yet; instead, do this on demand
    fSourceArray = new ByteStreamFileSource*[fNumSources];
    if (fSourceArray == NULL) return;
    for (i = 0; i < fNumSources; ++i) {
      fSourceArray[i] = NULL;
    }
}

ByteStreamMultiFileSource::~ByteStreamMultiFileSource() {
  unsigned i;
  for (i = 0; i < fNumSources; ++i) {
    Medium::close(fSourceArray[i]);
  }
  delete[] fSourceArray;

  for (i = 0; i < fNumSources; ++i) {
    delete[] (char*)(fFileNameArray[i]);
  }
  delete[] fFileNameArray;
}

ByteStreamMultiFileSource* ByteStreamMultiFileSource
::createNew(UsageEnvironment& env, char const** fileNameArray,
	    unsigned preferredFrameSize, unsigned playTimePerFrame) {
  ByteStreamMultiFileSource* newSource
    = new ByteStreamMultiFileSource(env, fileNameArray,
				    preferredFrameSize, playTimePerFrame);

  return newSource;
}

void ByteStreamMultiFileSource::doGetNextFrame() {
  do {
    // First, check whether we've run out of sources:
    if (fCurrentlyReadSourceNumber >= fNumSources) break;

    fHaveStartedNewFile = False;
    ByteStreamFileSource*& source
      = fSourceArray[fCurrentlyReadSourceNumber];
    if (source == NULL) {
      // The current source hasn't been created yet.  Do this now:
      source = ByteStreamFileSource::createNew(envir(),
		       fFileNameArray[fCurrentlyReadSourceNumber],
		       fPreferredFrameSize, fPlayTimePerFrame);
      if (source == NULL) break;
      fHaveStartedNewFile = True;
    }

    // (Attempt to) read from the current source.
    source->getNextFrame(fTo, fMaxSize,
			       afterGettingFrame, this,
			       onSourceClosure, this);
    return;
  } while (0);

  // An error occurred; consider ourselves closed:
  handleClosure();
}

void ByteStreamMultiFileSource
  ::afterGettingFrame(void* clientData,
		      unsigned frameSize, unsigned numTruncatedBytes,
		      struct timeval presentationTime,
		      unsigned durationInMicroseconds) {
  ByteStreamMultiFileSource* source
    = (ByteStreamMultiFileSource*)clientData;
  source->fFrameSize = frameSize;
  source->fNumTruncatedBytes = numTruncatedBytes;
  source->fPresentationTime = presentationTime;
  source->fDurationInMicroseconds = durationInMicroseconds;
  FramedSource::afterGetting(source);
}

void ByteStreamMultiFileSource::onSourceClosure(void* clientData) {
  ByteStreamMultiFileSource* source
    = (ByteStreamMultiFileSource*)clientData;
  source->onSourceClosure1();
}

void ByteStreamMultiFileSource::onSourceClosure1() {
  // This routine was called because the currently-read source was closed
  // (probably due to EOF).  Close this source down, and move to the
  // next one:
  ByteStreamFileSource*& source
    = fSourceArray[fCurrentlyReadSourceNumber++];
  Medium::close(source);
  source = NULL;

  // Try reading again:
  doGetNextFrame();
}
