// doDraw
//---------------------------------------------------------------------------
void RankView::doDraw(Surface &viewArea, Surface &clientArea)
{
    unsigned int flagHeight = ResourceManager::getFlag(0)->getHeight();
    unsigned int newheight = HEADER_HEIGHT
                             + (TABLE_BORDER * 2)
                             + (ENTRY_HEIGHT * PlayerInterface::countPlayers())
                             + DEFAULT_MOVE_AREA_HEIGHT
                             + (DEFAULT_BORDER_SIZE * 2);

    if ( newheight != (unsigned int)getSizeY() )
    {
        resize(WINDOW_WIDTH, newheight);
        return; // this frame draws nothing
    }
    
    bltViewBackground(viewArea);

    clientArea.drawButtonBorder(
            iRect(0, TABLE_BORDER_START, clientArea.getWidth()-1, clientArea.getHeight()-1),
            Color::gray64, Color::white);

    clientArea.bltStringShadowed(0, 16, table_header, Color::red, Color::gray64);
    drawPlayerStats(clientArea, flagHeight);

    View::doDraw(viewArea, clientArea);
} // end doDraw
// doDraw
//---------------------------------------------------------------------------
void LibView::doDraw(Surface &viewArea, Surface &clientArea)
{
    //bltViewBackground(viewArea);

    int x       =   5;
    int y       = 135;
    //int yOffset =  15;
    bltViewBackground(viewArea);

    switch(displayMode) {
    case LIBVIEW_MODE_SURFACE_INFO: {
            drawSurfaceInfo(clientArea, iXY(x, y));
        }
        break;
    case LIBVIEW_MODE_PARTICLE_INFO: {
            drawParticleInfo(clientArea, iXY(x, y));
        }
        break;
    case LIBVIEW_MODE_ENVIRONMENT_INFO: {
            drawEnvironmentInfo(clientArea, iXY(x, y));
        }
        break;
    }

    View::doDraw(viewArea, clientArea);

} // end LibView::doDraw
// doDraw
//---------------------------------------------------------------------------
void GameToolbarView::doDraw(const Surface &viewArea, const Surface &clientArea)
{
	bltViewBackground(viewArea);

	View::doDraw(viewArea, clientArea);

} // end GameToolbarView::doDraw
// doDraw
//---------------------------------------------------------------------------
void CodeStatsView::doDraw(Surface &viewArea, Surface &clientArea)
{
    bltViewBackground(viewArea);

    switch( display_mode ) {
    case _display_mode_network_stats :
        drawNetworkStats( clientArea );
        break;

    case _display_mode_sorter_stats :
        drawSorterStats( clientArea );
        break;

    case _display_mode_pathing_stats :
        drawPathingStats( clientArea );
        break;

    case _display_mode_unit_stats :
        drawUnitStats( clientArea );
        break;
    }

    /*
    char strBuf[256];

    sprintf(strBuf, "Packet Size : %d", gPacketSize );

    clientArea.bltString(2, INFO_AREA_Y_OFFSET - 18, strBuf, Color::white);
    */
    View::doDraw(viewArea, clientArea);

} // end CodeStatsView::doDraw
// doDraw
//---------------------------------------------------------------------------
void RankView::doDraw(const Surface &viewArea, const Surface &clientArea)
{
    bltViewBackground(viewArea);

    clientArea.drawButtonBorder(iRect(0, 26, getClientRect().getSize().x - 1, getClientRect().getSize().y - 1), Color::gray64, Color::white);

    drawPlayerStats(clientArea);

    View::doDraw(viewArea, clientArea);

} // end doDraw
// doDraw
//---------------------------------------------------------------------------
void HelpScrollView::doDraw(const Surface &viewArea, const Surface &clientArea)
{
    if (Desktop::getVisible("GameView")) {
        bltViewBackground(viewArea);
    }

    drawHelpText(clientArea, 0, 0);

    iXY pos;

    pos.x = 4;
    pos.y = clientArea.getPixY() - CHAR_YPIX;

    clientArea.bltString(pos, "Note: Use the right mouse button to accomplish fast mouse clicking.", Color::white);

    //char strBuf[256];
    //sprintf(strBuf, "%d", scrollBar->getValue());
    //clientArea.bltStringCenter(strBuf, Color::red);

    View::doDraw(viewArea, clientArea);
} // end HelpScrollView::doDraw
// doDraw
//---------------------------------------------------------------------------
void RankView::doDraw(Surface &viewArea, Surface &clientArea)
{
    // make sure the window is big enough for all players
    unsigned int CHAR_YPIX = Surface::getFontHeight();
    unsigned int entryheight = std::max(CHAR_YPIX, UNIT_FLAGS_SURFACE.getHeight()) + 2;
    unsigned int newheight = 60 + entryheight * PlayerInterface::countPlayers();

    if ( newheight != (unsigned int)getSizeY() ) {
        resize(iXY(450, newheight));
        return; // this frame draws nothing
    }

    bltViewBackground(viewArea);

    clientArea.drawButtonBorder(
        iRect(0, 26, getClientRect().getSize().x - 1,
              getClientRect().getSize().y - 1), Color::gray64, Color::white);

    drawPlayerStats(clientArea);

    View::doDraw(viewArea, clientArea);
} // end doDraw
// doDraw
//---------------------------------------------------------------------------
void CodeStatsView::doDraw(Surface &viewArea, Surface &clientArea)
{
    bltViewBackground(viewArea);

    switch( display_mode ) {
    case _display_mode_network_stats :
        drawNetworkStats( clientArea );
        break;

    case _display_mode_sorter_stats :
        drawSorterStats( clientArea );
        break;

    case _display_mode_pathing_stats :
        drawPathingStats( clientArea );
        break;

    case _display_mode_unit_stats :
        drawUnitStats( clientArea );
        break;
    }

    View::doDraw(viewArea, clientArea);
} // end CodeStatsView::doDraw
// doDraw
//---------------------------------------------------------------------------
void RankView::doDraw( Surface& dest )
{
    unsigned int flagHeight = ResourceManager::getFlag(0)->getHeight();
    unsigned int newheight = HEADER_HEIGHT
                             + (TABLE_BORDER * 2)
                             + (ENTRY_HEIGHT * PlayerInterface::countPlayers());

    if ( newheight != (unsigned int)getHeight() )
    {
        resize(WINDOW_WIDTH, newheight);
        return; // this frame draws nothing
    }
    
    bltViewBackground(dest);

//    dest.drawButtonBorder(
//            iRect(0, TABLE_BORDER_START, dest.getWidth()-1, dest.getHeight()-1),
//            Color::gray64, Color::white);

    dest.bltStringShadowed(0, 16, table_header, Color::red, Color::gray64);
    drawPlayerStats(dest, flagHeight);

    View::doDraw( dest);
} // end doDraw
// doDraw
//--------------------------------------------------------------------------
void VehicleSelectionView::doDraw( Surface& dest )
{
    Objective* obj = ObjectiveInterface::getObjective(CURRENT_SELECTED_OUTPOST_ID);
    if ( !obj || obj->occupying_player != PlayerInterface::getLocalPlayer() )
    {
//        Desktop::setVisibilityNoDoAnything("VehicleSelectionView", false);
        changeMade = false;
        return;
    }
    
    char strBuf[256];

    const int color = Color::white;

    // Draw a line attaching the VehicleSelectionView to its outpost.
    {if (WorldInputCmdProcessor::isObjectiveSelected())
        {
            // Draw a line connecting the vehicleSelectionView and the objective.
            iRect gameViewRect;
            WorldViewInterface::getViewWindow(&gameViewRect);

            iXY objectivePos(WorldInputCmdProcessor::getSelectedObjectiveWorldPos());
            objectivePos -= gameViewRect.getLocation();

            iXY a(VehicleSelectionView::getLocation() + VehicleSelectionView::getSize() / 2);
            iXY b(objectivePos);

            // Calculate the starting point on the outside of the vehicleSelectionView box.
            fXY v2oSlope(Math::unitDirection(a, b));

            a.x += int(v2oSlope.x * float(VehicleSelectionView::getWidth() / 2));
            a.y += int(v2oSlope.y * float(VehicleSelectionView::getHeight() / 2));

            // Calculate the starting point on the outside of the objective box.
            iXY objectiveOutlineSize(3, 3);

            //fXY o2vSlope(Math::unitDirection(b, a));

            //b.x += o2vSlope.x * float(objectiveOutlineSize.x);
            //b.y += o2vSlope.y * float(objectiveOutlineSize.y);

            //screen.drawLine(a, b, Color::white);

            iRect r(objectivePos.x - objectiveOutlineSize.x,
                    objectivePos.y - objectiveOutlineSize.y,
                    objectiveOutlineSize.x,
                    objectiveOutlineSize.y);

            screen->fillRect(r, Color::white);

            //int xOffset = (strlen(WorldInputCmdProcessor::getSelectedObjectiveName()) * CHAR_XPIX) / 2;

            //screen.bltStringShadowed(r.min.x - xOffset, r.min.y - 15, WorldInputCmdProcessor::getSelectedObjectiveName(), Color::white, Color::black);

            iXY oos(objectiveOutlineSize);
            iXY cpos;

            if (v2oSlope.x > 0 && v2oSlope.y > 0) {
                cpos = iXY(getEndX(), getEndY());
                r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y);
            }
            if (v2oSlope.x > 0 && v2oSlope.y <= 0) {
                cpos = iXY(getEndX(), getLocationY());
                r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y);
            }
            if (v2oSlope.x <= 0 && v2oSlope.y > 0) {
                cpos = iXY(getLocationX(), getEndY());
                r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y);
            }
            if (v2oSlope.x <= 0 && v2oSlope.y <= 0) {
                cpos = iXY(getLocationX(), getLocationY());
                r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y);
            }
//
            screen->drawLine(cpos, b, Color::white);
            screen->fillRect(r, Color::white);

            //screen.bltLookup(r, Palette::darkGray256.getColorArray());
            //screen.drawButtonBorder(r, Color::white, Color::gray96);

            // Draw the name of the outpost.
        }}

    bltViewBackground(dest);

    int remaining_time = 0;
    int generation_time = 0;

    if ( obj->unit_generation_on_flag )
    {
        remaining_time = obj->unit_generation_timer.getTimeLeft();
        UnitProfile* profile = UnitProfileInterface::getUnitProfile(obj->unit_generation_type);
        generation_time = profile->regen_time;
    }

    if (vsvUnitGenOn)
    {
        sprintf(strBuf, "%s", getUnitName(vsvSelectedUnit));
        dest.bltString(   productionUnitPos.x, productionUnitPos.y, 
                                strBuf, color);

        sprintf(strBuf, "%01d:%02d/%01d:%02d",
                        remaining_time / 60, remaining_time % 60,
                        generation_time / 60, generation_time % 60);
         
        dest.bltString(   timeRequiredPos.x, timeRequiredPos.y, 
                                strBuf, color);
    }
    else
    {
        sprintf(strBuf, "%s", _("power off"));
        dest.bltString(   productionUnitPos.x, productionUnitPos.y, 
                                strBuf, color);
        dest.bltString(   timeRequiredPos.x, timeRequiredPos.y, 
                                strBuf, color);
    }

    int unitPerPlayer = GameConfig::game_maxunits / GameConfig::game_maxplayers;
    sprintf(strBuf, "%d/%d", int(UnitInterface::getUnitCount(PlayerInterface::getLocalPlayerIndex())), unitPerPlayer);
    dest.bltString(unitsBuiltPos.x, unitsBuiltPos.y, strBuf, color);

    drawUnitProfileInfo(dest, iXY(0, unitProfileDataY), highlightedUnitType);

    //sprintf(strBuf, "%01d:%02d", ( (int) outpost_status.unit_generation_time_remaining ) / 60, ( (int) outpost_status.unit_generation_time_remaining) % 60 );
    //clientArea.bltString(timeRemainingPos, strBuf, color);

    View::doDraw( dest );

} // end VehicleSelectionView::doDraw
// doDraw
//--------------------------------------------------------------------------
void VehicleSelectionView::doDraw(Surface &viewArea, Surface &clientArea)
{
    char strBuf[256];

    const int color = Color::white;

    // Draw a line attaching the VehicleSelectionView to its outpost.
    {if (WorldInputCmdProcessor::isObjectiveSelected())
        {
            // Draw a line connecting the vehicleSelectionView and the objective.
            iRect gameViewRect;
            WorldViewInterface::getViewWindow(&gameViewRect);

            iXY objectivePos(WorldInputCmdProcessor::getSelectedObjectiveWorldPos());
            objectivePos -= gameViewRect.min;

            iXY a(VehicleSelectionView::min + VehicleSelectionView::getSize() / 2);
            iXY b(objectivePos);

            // Calculate the starting point on the outside of the vehicleSelectionView box.
            fXY v2oSlope(Math::unitDirection(a, b));

            a.x += int(v2oSlope.x * float(VehicleSelectionView::getSizeX() / 2));
            a.y += int(v2oSlope.y * float(VehicleSelectionView::getSizeY() / 2));

            // Calculate the starting point on the outside of the objective box.
            iXY objectiveOutlineSize(3, 3);

            //fXY o2vSlope(Math::unitDirection(b, a));

            //b.x += o2vSlope.x * float(objectiveOutlineSize.x);
            //b.y += o2vSlope.y * float(objectiveOutlineSize.y);

            //screen.drawLine(a, b, Color::white);

            iRect r(objectivePos - objectiveOutlineSize, objectivePos + objectiveOutlineSize);
            //bltBlendRect(screen, r);
            screen->fillRect(r, Color::white);

            //int xOffset = (strlen(WorldInputCmdProcessor::getSelectedObjectiveName()) * CHAR_XPIX) / 2;

            //screen.bltStringShadowed(r.min.x - xOffset, r.min.y - 15, WorldInputCmdProcessor::getSelectedObjectiveName(), Color::white, Color::black);

            iXY oos(objectiveOutlineSize);
            iXY cornerPos;

            if (v2oSlope.x > 0 && v2oSlope.y > 0) {
                cornerPos = iXY(max.x, max.y);
                r = iRect(cornerPos - oos, cornerPos + oos);
            }
            if (v2oSlope.x > 0 && v2oSlope.y <= 0) {
                cornerPos = iXY(max.x, min.y);
                r = iRect(cornerPos - oos, cornerPos + oos);
            }
            if (v2oSlope.x <= 0 && v2oSlope.y > 0) {
                cornerPos = iXY(min.x, max.y);
                r = iRect(cornerPos - oos, cornerPos + oos);
            }
            if (v2oSlope.x <= 0 && v2oSlope.y <= 0) {
                cornerPos = iXY(min.x, min.y);
                r = iRect(cornerPos - oos, cornerPos + oos);
            }

            screen->drawLine(cornerPos, b, Color::white);
            screen->fillRect(r, Color::white);

            //screen.bltLookup(r, Palette::darkGray256.getColorArray());
            //screen.drawButtonBorder(r, Color::white, Color::gray96);

            // Draw the name of the outpost.
        }}

    bltViewBackground(viewArea);

    OutpostStatus outpost_status;

    outpost_status = ObjectiveInterface::getOutpostStatus( CURRENT_SELECTED_OUTPOST_ID );

    if (vsvUnitGenOn) {
        sprintf(strBuf, "%s", getUnitName(vsvSelectedUnit));
        clientArea.bltString(   productionUnitPos.x, productionUnitPos.y, 
                                strBuf, color);

        sprintf(strBuf, "%01d:%02d/%01d:%02d",
                    ((int)outpost_status.unit_generation_time_remaining) / 60,
                    ((int)outpost_status.unit_generation_time_remaining) % 60,
                    ((int)outpost_status.unit_generation_time) / 60,
                    ((int)outpost_status.unit_generation_time) % 60);
         
        clientArea.bltString(   timeRequiredPos.x, timeRequiredPos.y, 
                                strBuf, color);
    } else {
        sprintf(strBuf, "power off");
        clientArea.bltString(   productionUnitPos.x, productionUnitPos.y, 
                                strBuf, color);

        sprintf(strBuf, "power off");
        clientArea.bltString(   timeRequiredPos.x, timeRequiredPos.y, 
                                strBuf, color);
    }

    int unitPerPlayer = gameconfig->maxunits / gameconfig->maxplayers;
    sprintf(strBuf, "%d/%d", int(UnitInterface::getUnitCount(PlayerInterface::getLocalPlayerIndex())), unitPerPlayer);
    clientArea.bltString(unitsBuiltPos.x, unitsBuiltPos.y, strBuf, color);

    drawUnitProfileInfo(clientArea, iXY(0, unitProfileDataY), highlightedUnitType);

    //sprintf(strBuf, "%01d:%02d", ( (int) outpost_status.unit_generation_time_remaining ) / 60, ( (int) outpost_status.unit_generation_time_remaining) % 60 );
    //clientArea.bltString(timeRemainingPos, strBuf, color);

    View::doDraw(viewArea, clientArea);

} // end VehicleSelectionView::doDraw
// doDraw
//---------------------------------------------------------------------------
void GameInfoView::doDraw(const Surface &viewArea, const Surface &clientArea)
{
    char unitsBuf[64];
    char killsBuf[64];
    char lossesBuf[64];
    char fragsBuf[64];
    char timeBuf[64];
    char pingBuf[64];
    char gameBuf[64];
    char fpsBuf[64];

    iXY pos(2, 2);

    // Resize the game info rect to nothing so it can be resized based on the text,
    // to be used in it.
    gameInfoRect = getClientRect();
    //gameInfoRect.max.x = 0;

    sprintf(gameBuf, "game   %s", GameConfig::getGameTypeString() );
    checkGameInfoRect(gameBuf);


    int unitPerPlayer = GameConfig::GetNumberUnits() / GameConfig::GetNumberPlayers();
    sprintf(unitsBuf, "units  %d/%d", int(UnitInterface::getUnitCount(PlayerInterface::getLocalPlayerIndex())), unitPerPlayer);
    checkGameInfoRect(unitsBuf);

    if( GameConfig::GetGameType() == _gametype_fraglimit )
    {
        sprintf(fragsBuf, "frags  %d/%d", getPlayerFrags(), GameConfig::GetFragLimit() );
        checkGameInfoRect(fragsBuf);
    }
    else
    {
        sprintf(fragsBuf, "frags  NA" );
        checkGameInfoRect(fragsBuf);
    }

    /*
    sprintf(killsBuf, "kills  %d", getPlayerKills());
    checkGameInfoRect(killsBuf);

    sprintf(lossesBuf, "losses %d", getPlayerLosses());
    checkGameInfoRect(lossesBuf);
    */

    if( GameConfig::GetGameType() == _gametype_timelimit )
    {
        sprintf(timeBuf, "time   %s/%s", (const char*) getPlayerTime(),
                (const char*) getTimeLimit() );
        checkGameInfoRect(timeBuf);
    }
    else
    {
        sprintf(timeBuf, "time   %s", (const char *) getPlayerTime() );
        checkGameInfoRect(timeBuf);
    }

    sprintf(pingBuf, "ping   %.0f ms", NetworkState::ping_time );
    checkGameInfoRect(pingBuf);

    sprintf(fpsBuf, "FPS    %f", TimerInterface::getFPSAvg() );
    checkGameInfoRect(fpsBuf);

    bltViewBackground(viewArea);

    clientArea.bltStringShadowed(pos, gameBuf, Color::white, Color::black);
    pos.y += 12;
    clientArea.bltStringShadowed(pos, unitsBuf, Color::white, Color::black);
    pos.y += 12;
    clientArea.bltStringShadowed(pos, fragsBuf, Color::white, Color::black);
    pos.y += 12;
    /*
    clientArea.bltStringShadowed(pos, killsBuf, Color::white, Color::black);
    pos.y += 12;
    clientArea.bltStringShadowed(pos, lossesBuf, Color::white, Color::black);
    pos.y += 12;
    */
    clientArea.bltStringShadowed(pos, timeBuf, Color::white, Color::black);
    pos.y += 12;
    clientArea.bltStringShadowed(pos, pingBuf, Color::white, Color::black);
    pos.y += 12;
    clientArea.bltStringShadowed(pos, fpsBuf, Color::white, Color::black);
    pos.y += 12;

    View::doDraw(viewArea, clientArea);

    // Make sure the view stays in the screen when the view is resized.
    //resizeClientArea(gameInfoRect.getSize());
    //moveTo(min);
} // end GameInfoView::doDraw