Пример #1
0
// Construct new indices without the reads in readsToRemove
void removeReadsFromIndices(const std::string& allReadsPrefix, const std::string& readsToRemove,
                             const std::string& outPrefix, const std::string& bwt_extension, 
                             const std::string& sai_extension, bool doReverse, int numThreads)
{
    std::string bwt_filename = makeFilename(allReadsPrefix, bwt_extension);
    std::string sai_filename = makeFilename(allReadsPrefix, sai_extension);

    // Prepare the input filehandle
    SeqReader* pReader = new SeqReader(readsToRemove);
    
    // Build the outnames
    std::string bwt_out_name = makeFilename(outPrefix, bwt_extension);
    std::string sai_out_name = makeFilename(outPrefix, sai_extension);

    // Compute the gap array
    BWT* pBWT = new BWT(bwt_filename, BWT_SAMPLE_RATE);

    // Boolean gap array
    GapArray* pGapArray = createGapArray(1);

    size_t num_strings_remove;
    size_t num_symbols_remove;
    computeGapArray(pReader, (size_t)-1, pBWT, doReverse, numThreads, pGapArray, true, num_strings_remove, num_symbols_remove);

    //writeRemovalIndex();
    writeRemovalIndex(pBWT, sai_filename, bwt_out_name, sai_out_name, num_strings_remove, num_symbols_remove, pGapArray);

    // Perform the actual merge
    //merge(pReader, item1, item2, bwt_merged_name, sai_merged_name, doReverse, numThreads);

    delete pGapArray;
    delete pReader;
    delete pBWT;
}
Пример #2
0
static bool mapToFile(MaConn *conn, bool *rescan)
{
    MaRequest   *req;
    MaResponse  *resp;

    req = conn->request;
    resp = conn->response;

    if (resp->filename == 0) {
        resp->filename = makeFilename(conn, req->alias, req->url, 1);
    }
    req->dir = maLookupBestDir(req->host, resp->filename);

    if (req->dir == 0) {
        maFailRequest(conn, MPR_HTTP_CODE_NOT_FOUND, "Missing directory block for %s", resp->filename);
        return 0;
    }

    mprAssert(req->dir);

    req->auth = req->dir->auth;

    if (!resp->fileInfo.valid && mprGetFileInfo(conn, resp->filename, &resp->fileInfo) < 0) {
#if UNUSED
        if (req->method & (MA_REQ_GET | MA_REQ_POST)) {
            maFailRequest(conn, MPR_HTTP_CODE_NOT_FOUND, "Can't open document: %s", resp->filename);
            return 0;
        }
#endif
    }
    if (resp->fileInfo.isDir) {
        processDirectory(conn, rescan);
    }
    return 1;
}
Пример #3
0
// Merge two readsFiles together
void mergeReadFiles(const std::string& readsFile1, const std::string& readsFile2, const std::string& outPrefix)
{
    // If the outfile is the empty string, append the reads in readsFile2 into readsFile1
    // otherwise cat the files together
    std::ostream* pWriter;
    if(outPrefix.empty())
    {
        pWriter = createWriter(readsFile1, std::ios_base::out | std::ios_base::app);
    }
    else
    {
        pWriter = createWriter(makeFilename(outPrefix, ".fa"));

        // Copy reads1 to the outfile
        SeqReader reader(readsFile1);
        SeqRecord record;
        while(reader.get(record))
            record.write(*pWriter);
    }

    // Copy reads2 to writer
    SeqReader reader(readsFile2);
    SeqRecord record;
    while(reader.get(record))
        record.write(*pWriter);
    delete pWriter;
}
Пример #4
0
//  TODO - should be MapUrl
char *maMapUriToStorage(MaConn *conn, cchar *url)
{
    MaAlias     *alias;

    alias = maGetAlias(conn->request->host, url);
    if (alias == 0) {
        return 0;
    }
    return makeFilename(conn, alias, url, 1);
}
Пример #5
0
// Merge the indices for the two independent sets of reads in readsFile1 and readsFile2
void mergeIndependentIndices(const std::string& readsFile1, const std::string& readsFile2, 
                             const std::string& outPrefix, const std::string& bwt_extension, 
                             const std::string& sai_extension, bool doReverse, int numThreads, int storageLevel)
{
    MergeItem item1;
    std::string prefix1 = stripFilename(readsFile1);
    item1.reads_filename = readsFile1;
    item1.bwt_filename = makeFilename(prefix1, bwt_extension);
    item1.sai_filename = makeFilename(prefix1, sai_extension);
    item1.start_index = 0;
    item1.end_index = -1; // this tells merge to read the entire file

    MergeItem item2;
    std::string prefix2 = stripFilename(readsFile2);
    item2.reads_filename = readsFile2;
    item2.bwt_filename = makeFilename(prefix2, bwt_extension);
    item2.sai_filename = makeFilename(prefix2, sai_extension);
    item2.start_index = 0;
    item2.end_index = -1;

    // Prepare the input filehandle
    SeqReader* pReader = new SeqReader(item1.reads_filename);
    
    // Build the outnames
    std::string bwt_merged_name = makeFilename(outPrefix, bwt_extension);
    std::string sai_merged_name = makeFilename(outPrefix, sai_extension);

    // Perform the actual merge
    merge(pReader, item1, item2, bwt_merged_name, sai_merged_name, doReverse, numThreads, storageLevel);
    delete pReader;
}
Пример #6
0
/*
 *  Search for a handler by request extension. If that fails, use handler custom matching.
 *  If all that fails, return the catch-all handler (fileHandler)
 */
static MaStage *findHandlerByExtension(MaConn *conn)
{
    MaRequest   *req;
    MaResponse  *resp;
    MaStage     *handler;
    MaLocation  *location;
    int         next;

    req = conn->request;
    resp = conn->response;
    location = req->location;
    
    resp->extension = getExtension(conn);

    if (*resp->extension) {
        handler = maGetHandlerByExtension(location, resp->extension);
        if (checkStage(conn, handler)) {
            return handler;
        }
    }

    /*
     *  Failed to match by extension, so perform custom handler matching. May need a filename (dir handler)
     */
    resp->filename = makeFilename(conn, req->alias, req->url, 1);
    for (next = 0; (handler = mprGetNextItem(location->handlers, &next)) != 0; ) {
        if (handler->match && handler->match(conn, handler, req->url)) {
            if (checkStage(conn, handler)) {
                resp->handler = handler;
                return handler;
            }
        }
    }

    /*
     *  Failed to match. Return any catch-all handler.
     */
    handler = maGetHandlerByExtension(location, "");
    if (handler == 0) {
        /*
         *  Could be missing a catch-all in the config file, so invoke the file handler.
         */
        handler = maLookupStage(conn->http, "fileHandler");
    }

    mprAssert(handler);
    //  TODO - should we be setting this here?
    resp->handler = handler;
    
    return checkStage(conn, handler);
}
Пример #7
0
void GraphicalReporter::openIndex()
{
	if (!m_indexStream.device())
	{
		m_indexFile.setFileName(m_generateImages? makeFilename("index.html") : m_output);
		if (!m_indexFile.open(QIODevice::WriteOnly | QIODevice::Text))
		{
			QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not open %1 for writing.").arg(m_indexFile.fileName()));        
			return;    
		}

		m_indexStream.setDevice(&m_indexFile);
	}
	m_indexStream.setCodec(QTextCodec::codecForName("UTF-8"));
}
Пример #8
0
int SplitKernel::execute()
{
    PointTable table;

    Options readerOpts;
    readerOpts.add("filename", m_inputFile);
    readerOpts.add("debug", isDebug());
    readerOpts.add("verbose", getVerboseLevel());

    Stage& reader = makeReader(m_inputFile);
    reader.setOptions(readerOpts);

    std::unique_ptr<Stage> f;
    StageFactory factory;
    Options filterOpts;
    if (m_length)
    {
        f.reset(factory.createStage("filters.splitter"));
        filterOpts.add("length", m_length);
        filterOpts.add("origin_x", m_xOrigin);
        filterOpts.add("origin_y", m_yOrigin);
    }
    else
    {
        f.reset(factory.createStage("filters.chipper"));
        filterOpts.add("capacity", m_capacity);
    }
    f->setInput(reader);
    f->setOptions(filterOpts);

    f->prepare(table);
    PointViewSet pvSet = f->execute(table);

    int filenum = 1;
    for (auto& pvp : pvSet)
    {
        BufferReader reader;
        reader.addView(pvp);

        std::string filename = makeFilename(m_outputFile, filenum++);
        Stage& writer = makeWriter(filename, reader);

        writer.prepare(table);
        writer.execute(table);
    }
    return 0;
}
Пример #9
0
static void setEnv(MaConn *conn)
{
    MaRequest       *req;
    MaResponse      *resp;
    MaStage         *handler;
    MprFileInfo     *info;

    req = conn->request;
    resp = conn->response;
    handler = resp->handler;

    setPathInfo(conn);

    if (resp->extension == 0) {
        resp->extension = getExtension(conn);
    }
    if (resp->filename == 0) {
        resp->filename = makeFilename(conn, req->alias, req->url, 1);
    }

    if ((resp->mimeType = (char*) maLookupMimeType(conn->host, resp->extension)) == 0) {
        resp->mimeType = (char*) "text/html";
    }

    if (!(resp->handler->flags & MA_STAGE_VIRTUAL)) {
        /*
         *  Define an Etag for physical entities. Redo the file info if not valid now that extra path has been removed.
         */
        info = &resp->fileInfo;
        if (!info->valid) {
            mprGetFileInfo(conn, resp->filename, info);
        }
        if (info->valid) {
            mprAllocSprintf(resp, &resp->etag, -1, "%x-%Lx-%Lx", info->inode, info->size, info->mtime);
        }
    }

    if (handler->flags & MA_STAGE_FORM_VARS) {
        req->formVars = mprCreateHash(req, MA_VAR_HASH_SIZE);
        if (req->parsedUri->query) {
            maAddFormVars(conn, req->parsedUri->query, (int) strlen(req->parsedUri->query));
        }
    }
    if (handler->flags & MA_STAGE_ENV_VARS) {
        maCreateEnvVars(conn);
    }
}
Пример #10
0
void Movie::record() {
  if(Movie::state != Inactive) {
    utility.showMessage("Movie mode already active, recording cancelled.");
  } else {
    SNES::system.runtosave();
    serializer state = SNES::system.serialize();

    utility.showMessage("Recording started.");

    Movie::state = Record;
    mainWindow->syncUi();
    fp.open(makeFilename(), file::mode::write);
    fp.writem(0x42535631, 4);
    fp.writel(SNES::Info::SerializerVersion, 4);
    fp.writel(SNES::cartridge.crc32(), 4);
    fp.writel(state.size(), 4);
    fp.write(state.data(), state.size());
  }
}
bool loadAllTracks(const std::string& tracks_format,
                   TrackListList& track_lists) {
  bool ok = true;
  bool have_frame = true;
  int t = 0;

  while (have_frame && ok) {
    // Check if file exists.
    std::string tracks_file = makeFilename(tracks_format, t);
    have_frame = fileExists(tracks_file);
    if (!have_frame) {
      // End of movie.
      continue;
    }

    // Add an empty track list.
    TrackList track_list;

    // Attempt to load tracks.
    SiftPositionReader feature_reader;
    ok = loadMultiviewTrackList(tracks_file, track_list, feature_reader);
    if (!ok) {
      // Failed.
      continue;
    }

    LOG(INFO) << "Read " << track_list.numTracks() << " tracks from `" <<
        tracks_file << "'";

    // Put into list.
    track_lists.push_back(TrackList());
    track_lists.back().swap(track_list);

    t += 1;
  }

  return ok;
}
Пример #12
0
int SplitKernel::execute()
{
    PointTable table;

    Stage& reader = makeReader(m_inputFile, m_driverOverride);

    Options filterOpts;
    std::string driver = (m_length ? "filters.splitter" : "filters.chipper");
    if (m_length)
    {
        filterOpts.add("length", m_length);
        filterOpts.add("origin_x", m_xOrigin);
        filterOpts.add("origin_y", m_yOrigin);
    }
    else
    {
        filterOpts.add("capacity", m_capacity);
    }
    Stage& f = makeFilter(driver, reader, filterOpts);
    f.prepare(table);
    PointViewSet pvSet = f.execute(table);

    int filenum = 1;
    for (auto& pvp : pvSet)
    {
        BufferReader reader;
        reader.addView(pvp);

        std::string filename = makeFilename(m_outputFile, filenum++);
        Stage& writer = makeWriter(filename, reader, "");

        writer.prepare(table);
        writer.execute(table);
    }
    return 0;
}
Пример #13
0
int main(int argc, char *argv[])
{
    const char *header = NULL;
    const char *output = NULL;
    gboolean check_only = FALSE;
    int verbose = 0, opt;
    GList *block_list = NULL;

    while( (opt = getopt_long( argc, argv, short_options, long_options, NULL )) != -1 ) {
        switch(opt) {
        case 'c':
            check_only = TRUE;
            break;
        case 'd':
            header = optarg;
            break;
        case 'h':
            print_usage();
            exit(0);
        case 'o':
            output = optarg;
            break;
        case 'v':
            verbose++;
            break;
        }
    }

    if( optind == argc ) {
        print_usage();
        exit(1);
    }

    if( output == NULL ) {
        output = makeFilename(argv[optind],".c");
    }
    if( header == NULL ) {
        header = makeFilename(argv[optind],".h");
    }

    for( ; optind < argc; optind++ ) {
        block_list = ioparse(argv[optind], block_list);
    }

    if( verbose ) {
        dump_register_blocks(stdout, block_list, verbose>1);
    }

    int errors = check_registers(block_list);
    if( errors != 0 ) {
        fprintf( stderr, "Aborting due to validation errors\n" );
        return 2;
    }

    if( !check_only ) {
        FILE *f = fopen( output, "wo" );
        if( f == NULL ) {
            fprintf( stderr, "Unable to open output file '%s': %s\n", output, strerror(errno) );
            return 3;
        }
        write_source( f, block_list, header );
        fclose(f);

        f = fopen( header, "wo" );
        if( f == NULL ) {
            fprintf( stderr, "Unable to open header file '%s': %s\n", header, strerror(errno) );
            return 4;
        }
        write_header( f, block_list );
        fclose(f);
    }

    for( GList *ptr = block_list; ptr != NULL; ptr = ptr->next ) {
        char *data = build_page_initializer((regblock_t)ptr->data);
        fwrite_dump( data, LXDREAM_PAGE_SIZE, stdout );
        g_free(data);
    }
    return 0;
}
Пример #14
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    // gui independent initialization
    // app specific
    const QString appversion="2.0.2";
    const QString appdate="04.07.2016";
    const QString appname="PIHK";
    const QString appauthor="Frank Zimmermann";
    const QString appemail="*****@*****.**";

    // Timer related
    isTimerStarted=false;
    timerValue=0;
    offset=0;
    const QString version =  appname + "   (V" +appversion +", vom " + appdate + ")";
    timer = new QTimer(this);


    ui->setupUi(this);

    // gui dependent initialization
#ifdef Q_OS_OSX
    // OSX---
    setWindowIcon(QIcon("pihk2.icns"));
#else
    // Windows Q_OS_WIN
    setWindowIcon(QIcon("pihk2.ico"));
#endif
    statusLabel = new QLabel(this);
    statusLabel->setText(appemail);
    this->setFixedSize(this->geometry().width(),this->geometry().height());
    ui->listViewPRFG->setStyleSheet("background-color:lightgray;");
    ui->listViewMEPR->setStyleSheet("background-color:lightgray;");

    // gui stuff
    ui->pDate->setDate(QDate::currentDate());   // set current Date
    ui->lcdNumber->setPalette(Qt::black);       // set color for LCD
    this->setWindowTitle(version);              // set title
    ui->statusBar->addPermanentWidget(statusLabel);
    makeFilename();                             // construct basic file name
    ui->labelGradeA->setStyleSheet("QLabel { color : red; }");
    ui->labelGradeB->setStyleSheet("QLabel { color : red; }");
    ui->labelGradeResultA->setStyleSheet("QLabel { color : red; }");
    ui->labelGradeResultB->setStyleSheet("QLabel { color : red; }");
    ui->labelGradeResult->setStyleSheet("QLabel { color : red; }");
    ui->spinboxGa1E->setEnabled(false);
    ui->spinboxGa1E->hide();
    ui->spinboxGa1E->setValue(0);
    ui->spinboxGa2E->setEnabled(false);
    ui->spinboxGa2E->hide();
    ui->spinboxGa2E->setValue(0);
    ui->spinboxWisoE->setEnabled(false);
    ui->spinboxWisoE->hide();
    ui->spinboxWisoE->setValue(0);
    ui->radioButton1->setEnabled(false);
    ui->radioButton2->setEnabled(false);
    ui->radioButton3->setEnabled(false);


    // Connections
    connect(timer,SIGNAL(timeout()),this,SLOT(updateProgressBar()));
    connect(ui->startTimer,SIGNAL(clicked()),this,SLOT(toggleStartStop()));
    connect(ui->resetTimer,SIGNAL(clicked()),this,SLOT(timerReset()));
    connect(ui->pname,SIGNAL(textChanged(QString)),this,SLOT(makeFilename()));
    connect(ui->pnummer,SIGNAL(textChanged(QString)),this,SLOT(makeFilename()));
    connect(ui->pDate,SIGNAL(dateChanged(QDate)),this,SLOT(makeFilename()));
    connect(ui->folder,SIGNAL(textChanged(QString)),this,SLOT(makeFilename()));
    connect(ui->spinboxDocumentation,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxExamination,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxGa1,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxGa2,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxWiso,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxGa1E,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxGa2E,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->spinboxWisoE,SIGNAL(valueChanged(double)),this,SLOT(writeResults()));
    connect(ui->radioButton1,SIGNAL(toggled(bool)),this,SLOT(writeResults()));
    connect(ui->radioButton2,SIGNAL(toggled(bool)),this,SLOT(writeResults()));
    connect(ui->radioButton3,SIGNAL(toggled(bool)),this,SLOT(writeResults()));
    connect(ui->saveFile,SIGNAL(clicked(bool)),this,SLOT(saveData()));
    connect(ui->buttonSimPRFG,SIGNAL(clicked()),this,SLOT(fillPRFG()));
    connect(ui->buttonSimMEPR,SIGNAL(clicked()),this,SLOT(fillMEPR()));
    connect(ui->listViewPRFG,SIGNAL(clicked(const QModelIndex &)),this,SLOT(setPointsPRFG(const QModelIndex &)));
    connect(ui->listViewMEPR,SIGNAL(clicked(const QModelIndex &)),this,SLOT(setPointsMEPR(const QModelIndex &)));
}
Пример #15
0
int main(int argc, char** argv) {
  init(argc, argv);

  if (argc != 3) {
    google::ShowUsageWithFlags(argv[0]);
    return 1;
  }

  std::string tracks_file = argv[1];
  std::string image_format = argv[2];
  std::string output_format = FLAGS_output_format;

  bool ok;

  TrackList<DrawerPointer> tracks;

  if (FLAGS_similarity) {
    // Load tracks.
    TrackList<SiftPosition> sift_tracks;
    SiftPositionReader feature_reader;
    ok = loadTrackList(tracks_file, sift_tracks, feature_reader);
    CHECK(ok) << "Could not load tracks";

    // Convert SIFT features to generic drawable features.
    siftPositionTracksToDrawers(sift_tracks, tracks);
  } else if (FLAGS_scale) {
    // Load tracks.
    TrackList<ScaleSpacePosition> scale_tracks;
    ScaleSpacePositionReader feature_reader;
    ok = loadTrackList(tracks_file, scale_tracks, feature_reader);
    CHECK(ok) << "Could not load tracks";

    // Convert SIFT features to generic drawable features.
    scaleFeatureTracksToDrawers(scale_tracks, tracks, FLAGS_radius);
  } else {
    // Load tracks.
    TrackList<cv::Point2d> point_tracks;
    ImagePointReader<double> feature_reader;
    ok = loadTrackList(tracks_file, point_tracks, feature_reader);
    CHECK(ok) << "Could not load tracks";

    // Convert SIFT features to generic drawable features.
    translationTracksToDrawers(point_tracks, tracks, FLAGS_radius);
  }

  LOG(INFO) << "Loaded " << tracks.size() << " tracks";

  // Make a list of random colors.
  typedef std::vector<cv::Scalar> ColorList;
  ColorList colors;
  for (int i = 0; i < int(tracks.size()); i += 1) {
    colors.push_back(randomColor(BRIGHTNESS, SATURATION));
  }

  // Iterate through frames in which track was observed.
  TrackListTimeIterator<DrawerPointer> frame(tracks, 0);

  while (!frame.end()) {
    // Get the current time.
    int t = frame.t();

    // Load the image.
    cv::Mat color_image;
    cv::Mat gray_image;
    ok = readImage(makeFilename(image_format, t), color_image, gray_image);
    CHECK(ok) << "Could not read image";

    // Get the features.
    typedef std::map<int, DrawerPointer> FeatureSet;
    FeatureSet features;
    frame.getPoints(features);

    // Draw each one with its color.
    drawFeatures(color_image, features, colors);

    if (FLAGS_save) {
      std::string output_file = makeFilename(output_format, t);
      ok = cv::imwrite(output_file, color_image);
      CHECK(ok) << "Could not save image";
    }

    if (FLAGS_display) {
      cv::imshow("tracks", color_image);
      cv::waitKey(10);
    }

    ++frame;
  }

  return 0;
}
Пример #16
0
/*
 *  Set the pathInfo (PATH_INFO) and update the request uri. This may set the response filename if convenient.
 */
static void setPathInfo(MaConn *conn)
{
    MaStage     *handler;
    MaAlias     *alias;
    MaRequest   *req;
    MaResponse  *resp;
    char        *last, *start, *cp, *pathInfo;
    int         found;

    req = conn->request;
    resp = conn->response;
    alias = req->alias;
    handler = resp->handler;

    mprAssert(handler);

    if (/* (req->location->flags & MA_LOC_PATH_INFO) || */ (handler && handler->flags & MA_STAGE_PATH_INFO)) {
        if (!(handler->flags & MA_STAGE_VIRTUAL)) {
            /*
             *  Find the longest subset of the filename that matches a real file. Test each segment to see if 
             *  it corresponds to a real physical file. This also defines a new response filename without the 
             *  extra path info.
             */
            last = 0;
            resp->filename = makeFilename(conn, alias, req->url, 1);
            for (cp = start = &resp->filename[strlen(alias->filename)]; cp; ) {
                
                if ((cp = strchr(cp, '/')) != 0) {
                    *cp = '\0';
                }
                found = fileExists(conn, resp->filename);
                if (cp) {
                    *cp = '/';
                }
                if (found) {
                    if (cp) {
                        last = cp++;
                    } else {
                        last = &resp->filename[strlen(resp->filename)];
                        break;
                    }
                } else {
                    break;
                }
            }
            if (last) {
                pathInfo = &req->url[alias->prefixLen + last - start];
                req->pathInfo = mprStrdup(req, pathInfo);
                *last = '\0';
                pathInfo[0] = '\0';
                if (req->pathInfo[0]) {
                    req->pathTranslated = makeFilename(conn, alias, req->pathInfo, 0);
                }
            }
        }
        if (req->pathInfo == 0) {
            req->pathInfo = req->url;
            req->url = "";

            if ((cp = strchr(req->pathInfo, '.')) != 0) {
                resp->extension = mprStrdup(req, ++cp);
            } else {
                resp->extension = "";
            }
            req->pathTranslated = makeFilename(conn, alias, req->pathInfo, 0); 
            resp->filename = alias->filename;
        }
    }
}
Пример #17
0
void GraphicalReporter::reportPosition(const Quackle::GamePosition &position, Quackle::ComputerPlayer *computerPlayer)
{
	openIndex();

	const QSize pictureSize(500, 500);

	Quackle::GamePosition positionCopy = position;

	{
		QString title;

		if (!position.gameOver())
		{
			title = GraphicalBoard::tr("<h2>%1: Turn %2</h2>").arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name())).arg(position.turnNumber());
		}
		else
		{
			title = GraphicalBoard::tr("<h2>Game over.</h2>");
		}

		if (m_generateImages)
		{
			QPixmap pixmap;
			positionCopy.resetMoveMade();
			GraphicalBoardFrame::staticDrawPosition(positionCopy, pictureSize, &pixmap);

			QImage image = pixmap.toImage();

			const QString filebasename = QString("%1-%2-position.png").arg(position.turnNumber()).arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name()));
			const QString filename = makeFilename(filebasename);

			if (image.save(filename, "PNG"))
			{
				m_indexStream << QString("<a href=\"%1\">%2</a>").arg(filebasename).arg(title) << endl;
			}
			else
			{
				QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not write image %1.").arg(filename));        
			}

			m_indexStream << "<p><img src=\"" << filebasename << "\"></p>" << endl;
		}
		else
		{
			m_indexStream << title;

			const int boardTileSize = position.gameOver()? 45 : 25;
			m_indexStream << QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::uvStringToQString(position.board().htmlBoard(boardTileSize))) << endl;
		}
	}

	const Quackle::PlayerList players(position.endgameAdjustedScores());

	m_indexStream << "<table cellspacing=6>" << endl;
	for (Quackle::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
	{
		m_indexStream << "<tr>";

		m_indexStream << "<td>";
		if ((*it) == position.currentPlayer())
			m_indexStream << "&rarr;";
		else
			m_indexStream << "&nbsp;";
		m_indexStream << "</td>";

		m_indexStream
		<< "<td>" << QuackleIO::Util::uvStringToQString((*it).name()) << "</td>"
		<< "<td>" << QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::uvStringToQString((*it).rack().toString())) << "</td>"
		<< "<td>" << (*it).score() << "</td>"
		<< "</tr>"
		<< endl;
	}
	m_indexStream << "</table>" << endl;

	if (computerPlayer && !position.gameOver())
	{
		computerPlayer->setPosition(position);

		if (position.committedMove().isAMove())
			computerPlayer->considerMove(position.committedMove());

		const unsigned int movesToShow = 5;
		Quackle::MoveList moves = computerPlayer->moves(movesToShow);

		if (!moves.contains(position.committedMove()))
		{
			if (moves.size() == movesToShow)
				moves.pop_back();

			moves.push_back(position.committedMove());
		}

		m_indexStream << "<ol>" << endl;
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != moves.end(); ++it)
		{
			QString item;
			switch ((*it).action)
			{
			case Quackle::Move::Place:
			case Quackle::Move::PlaceError:
			{
				if (m_generateImages)
				{
					QPixmap pixmap;

					positionCopy.setMoveMade(*it);
					GraphicalBoardFrame::staticDrawPosition(positionCopy, pictureSize, &pixmap);

					QImage image = pixmap.toImage();

					const QString filebasename = QString("%1-%2-%3-%4.png").arg(position.turnNumber()).arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name())).arg(QuackleIO::Util::letterStringToQString((*it).prettyTiles())).arg(QuackleIO::Util::uvStringToQString((*it).positionString()));
					const QString filename = makeFilename(filebasename);

					if (image.save(filename, "PNG"))
					{
						item = QString("<a href=\"%1\">%2</a> %3").arg(filebasename);
					}
					else
					{
						QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not write image %1.").arg(filename));        
					}
				}
				else
				{
					item = "%1 %2";
				}

				item = item.arg(QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::moveToDetailedString(*it))).arg((*it).score);
				break;
			}

			case Quackle::Move::Exchange:
			case Quackle::Move::BlindExchange:
			default:
				item = QuackleIO::Util::moveToDetailedString(*it);
				break;
			}

			if (*it == position.committedMove())
				item += QString(" &nbsp;&larr;");

			if (!item.isEmpty())
				m_indexStream << "<li>" << item << "</li>" << endl;
		}
		m_indexStream << "</ol>" << endl;
	}

	m_indexStream << "\n\n";
}