void FileSendProgressDialog::sendFile(const FileInfo& info)
{
    QFile f( info.fileID == -1 ? QDir::toNativeSeparators(info.fileName) : fileUtils()->resolveFilePath(info.fileID) );
    if (!f.open(QIODevice::ReadOnly))
    {
        qDebug() << "Could not open file for reading" << f.fileName()<<f.errorString();
        reject();
        return;
    }
    m_fileSize = f.size();
    f.seek(info.offset);
    setRange(0, 100);
    qDebug()<<"sendFile:"<<f.fileName();
    
    // we do the whole splitting thing, since when sending the header
    // we don't want the whole path
    FileInfo copy = info;
    if (info.fileID == -1)
    {
        copy.fileName = info.fileName.split('/').last();
        qDebug() << "sendFile: " << copy.fileName;
        writeBlock(fileUtils()->formatFileHeader(copy).toAscii());
    }
    //qDebug() << fileUtils()->formatFileHeader(copy).toAscii();
    //if (copy.fileName.contains("elf.h"))
    //    qDebug() << "Elf " << fileUtils()->formatFileHeader(copy).toAscii();
    m_writingData = true;
    qDebug() << "sendFile: Calling writeFile";
    writeFile(m_socket, &f);
    //nextFileRequested();
}
/*
 * FileInfo.type = -1 if there was an error parsing the header
 */
FileInfo FileSendProgressDialog::parseIncomingFileRequest(const QByteArray& b)
{
    FileInfo info;
    qDebug() << "parseIncomingFileRequest : " << b;
    QList<QByteArray> tokens = b.split(':');
    if (tokens.size() < 7)
    {
        qDebug() << "Bad header" << tokens;
        info.type = -1;
    }
    else
    {
        int command = tokens[4].toInt();
        info.fileID = tokens[6].toInt(0, 16);
        
        // for now we just store the file name, later we'll resolve the path
        info.fileName = QFileInfo(fileUtils()->resolveFilePath(info.fileID)).fileName();
        
        if ((command & QOM_COMMAND_MASK) == QOM_GETDIRFILES)
            info.type = QOM_FILE_DIR;
        else if ((command & QOM_COMMAND_MASK) == QOM_GETFILEDATA)
        {
            info.type = QOM_FILE_REGULAR;
            info.offset = tokens[7].toInt();
        }
    }
    return info;
}
void FileSendProgressDialog::sendDir(const FileInfo& info)
{
    QList<FileInfo> headers = fileUtils()->directoryInfoList(
                            info.fileID == -1 ? info.fileName : fileUtils()->resolveFilePath(info.fileID));
    
    FileInfo copy = headers.takeFirst();
    copy.fileName = copy.fileName.split('/').last();
    qDebug() << copy.fileName;
    //qDebug() << "sendDir: " << fileUtils()->formatFileHeader(copy).toAscii() << m_writingData;
    writeBlock(fileUtils()->formatFileHeader(copy).toAscii());
    
    // this swap is to prepend the new sub directory entries
    // so that they follow the directory name
    headers += m_fileList;
    m_fileList = headers;
    //nextFileRequested();
    //qDebug() << "sendDir : done";
}
RegionTemplateCollection* RTFromFiles(std::string inputFolderPath){
	// Search for input files in folder path
	FileUtils fileUtils(".mask.png");
	std::vector<std::string> fileList;
	fileUtils.traverseDirectoryRecursive(inputFolderPath, fileList);
	RegionTemplateCollection* rtCollection = new RegionTemplateCollection();
	rtCollection->setName("inputimage");

	std::cout << "Input Folder: "<< inputFolderPath <<std::endl;
	if(fileList.size() > 0)
		std::cout << "FILELIST[0]: "<< fileList[0] <<std::endl;

	std::string temp;
	// Create one region template instance for each input data file
	// (creates representations without instantiating them)
	for(int i = 0; i < fileList.size(); i++){

		// Create input mask data region
		DenseDataRegion2D *ddr2d = new DenseDataRegion2D();
		ddr2d->setName("RAW");
		std::ostringstream oss;
		oss << i;
		ddr2d->setId(oss.str());
		ddr2d->setInputType(DataSourceType::FILE_SYSTEM);
		ddr2d->setIsAppInput(true);
		ddr2d->setOutputType(DataSourceType::FILE_SYSTEM);

		std::string inputFileName = fileUtils.replaceExt(fileList[i], ".mask.png", ".tif");
		ddr2d->setInputFileName(inputFileName);

		// Create reference mask data region
		DenseDataRegion2D *ddr2dRefMask = new DenseDataRegion2D();
		ddr2dRefMask->setName("REF_MASK");
		ddr2dRefMask->setId(oss.str());
		ddr2dRefMask->setInputType(DataSourceType::FILE_SYSTEM);
		ddr2dRefMask->setIsAppInput(true);
		ddr2dRefMask->setOutputType(DataSourceType::FILE_SYSTEM);
		ddr2dRefMask->setInputFileName(fileList[i]);

		// Adding data regions to region template
		RegionTemplate *rt = new RegionTemplate();
		rt->setName("tile");
		rt->insertDataRegion(ddr2d);
		rt->insertDataRegion(ddr2dRefMask);

		// Adding region template instance to collection
		rtCollection->addRT(rt);
	}

	return rtCollection;
}
void FileSendProgressDialog::nextFileRequested()
{
    //qDebug() << "nextFileRequested : entered"<<m_writingData << (m_fileList.empty() ? "" : m_fileList[0].fileName);
    if (m_socket->bytesAvailable())
    {
        qDebug() << "nextFileRequested : parsing header";
        FileInfo next = parseIncomingFileRequest(m_socket->readAll());
        if (next.fileID != -1)
            m_fileList << next;
        qDebug() << "nextFileRequested : header parse done";
    }
    
    if (!m_fileList.empty())
    {
        if (m_writingData)
        {
            //qDebug() << "nextFileRequested exiting";
            return;
        }
        //qDebug() << "nextFileRequested : attempting send";
        FileInfo first = m_fileList.takeFirst();
        //qDebug() << first.fileName << first.type;
        if (first.type == QOM_FILE_REGULAR)
            sendFile(first);
        else if (first.type == QOM_FILE_DIR)
            sendDir(first);
        else if (first.type == QOM_FILE_RETPARENT)
        {
            //qDebug() << fileUtils()->formatFileHeader(first).toAscii();
            writeBlock(fileUtils()->formatFileHeader(first).toAscii());
        }
        if (m_sendBuffer.size()>0)
            writeBlock("");
        nextFileRequested();
    }
    else
    {
        qDebug() << "We're done sending";
        accept();
    }
}