/*
* Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program 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 General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* AELITIS, SAS au capital de 46,603.30 euros,
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package org.gudy.azureus2.ui.swt.views.tableitems.pieces;
import java.util.Arrays;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.gudy.azureus2.core3.disk.DiskManager;
import org.gudy.azureus2.core3.peer.PEPiece;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.ui.swt.mainwindow.Colors;
import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerFactory;
import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerStats;
import org.gudy.azureus2.plugins.ui.Graphic;
import org.gudy.azureus2.plugins.ui.tables.*;
/**
*
* @author TuxPaper
* @since 2.0.8.5
*/
public class BlocksItem
extends CoreTableColumn
implements TableCellAddedListener, TableCellRefreshListener,
TableCellDisposeListener
{
private final int COLOR_REQUESTED = 0;
private final int COLOR_WRITTEN = 1;
private final int COLOR_DOWNLOADED = 2;
private final int COLOR_INCACHE = 3;
public static Color[] colors = new Color[] {
Colors.blues[Colors.BLUES_MIDLIGHT],
Colors.blues[Colors.BLUES_DARKEST],
Colors.red,
Colors.grey
};
private static CacheFileManagerStats cacheStats = null;
/** Default Constructor */
public BlocksItem() {
super("blocks", TableManager.TABLE_TORRENT_PIECES);
initializeAsGraphic(POSITION_LAST, 200);
}
public void fillTableColumnInfo(TableColumnInfo info) {
info.addCategories(new String[] {
CAT_PROGRESS,
});
}
public void cellAdded(TableCell cell) {
if (cacheStats == null) {
try {
cacheStats = CacheFileManagerFactory.getSingleton().getStats();
} catch (Exception e) {
e.printStackTrace();
}
}
cell.setFillCell(true);
}
public void dispose(TableCell cell) {
Image img = ((TableCellSWT) cell).getGraphicSWT();
if (img != null && !img.isDisposed())
img.dispose();
}
public void refresh(TableCell cell) {
PEPiece pePiece = (PEPiece) cell.getDataSource();
if (pePiece == null) {
cell.setSortValue(0);
dispose(cell);
cell.setGraphic(null);
return;
}
cell.setSortValue(pePiece.getNbWritten());
long lNumBlocks = pePiece.getNbBlocks();
int newWidth = cell.getWidth();
if (newWidth <= 0) {
dispose(cell);
cell.setGraphic(null);
return;
}
int newHeight = cell.getHeight();
int x1 = newWidth - 2;
int y1 = newHeight - 3;
if (x1 < 10 || y1 < 3) {
dispose(cell);
cell.setGraphic(null);
return;
}
Image image = new Image(SWTThread.getInstance().getDisplay(), newWidth,
newHeight);
Color color;
GC gcImage = new GC(image);
gcImage.setForeground(Colors.grey);
gcImage.drawRectangle(0, 0, x1 + 1, y1 + 1);
int blocksPerPixel = 0;
int iPixelsPerBlock = 0;
int pxRes = 0;
long pxBlockStep = 0;
int factor = 4;
while (iPixelsPerBlock <= 0) {
blocksPerPixel++;
iPixelsPerBlock = (int) ((x1 + 1) / (lNumBlocks / blocksPerPixel));
}
pxRes = (int) (x1 - ((lNumBlocks / blocksPerPixel) * iPixelsPerBlock)); // kolik mi zbyde
if (pxRes <= 0)
pxRes = 1;
pxBlockStep = (lNumBlocks * factor) / pxRes; // kolikaty blok na +1 k sirce
long addBlocks = (lNumBlocks * factor) / pxBlockStep;
if ((addBlocks * iPixelsPerBlock) > pxRes)
pxBlockStep += 1;
/* String msg = "iPixelsPerBlock = "+iPixelsPerBlock + ", blocksPerPixel = " + blocksPerPixel;
msg += ", pxRes = " + pxRes + ", pxBlockStep = " + pxBlockStep + ", addBlocks = " + addBlocks + ", x1 = " + x1;
Debug.out(msg);*/
TOTorrent torrent = pePiece.getManager().getDiskManager().getTorrent();
boolean[] written = pePiece.getDMPiece().getWritten();
boolean piece_written = pePiece.isWritten();
int drawnWidth = 0;
int blockStep = 0;
int pieceNumber = pePiece.getPieceNumber();
long[] offsets = new long[(int) lNumBlocks];
long[] lengths = (long[]) offsets.clone();
Arrays.fill(offsets,
(long) pePiece.getManager().getDiskManager().getPieceLength()
* (long) pieceNumber);
for (int i = 0; i < lNumBlocks; lengths[i] = pePiece.getBlockSize(i), offsets[i] += DiskManager.BLOCK_SIZE * i, i++)
;
boolean[] isCached = cacheStats == null ? null
: cacheStats.getBytesInCache(torrent, offsets, lengths);
for (int i = 0; i < lNumBlocks; i += blocksPerPixel) {
int nextWidth = iPixelsPerBlock;
blockStep += blocksPerPixel * factor;
if (blockStep >= pxBlockStep) { // pokud jsem prelezl dany pocet bloku, zvys tomuhle sirku
nextWidth += (int) (blockStep / pxBlockStep);
blockStep -= pxBlockStep;
}
if (i >= lNumBlocks - blocksPerPixel) { // pokud je posledni, at zasahuje az na konec
nextWidth = x1 - drawnWidth;
}
color = Colors.white;
if ((written == null && piece_written) || (written != null && written[i])) {
color = colors[COLOR_WRITTEN];
} else if (pePiece.isDownloaded(i)) {
color = colors[COLOR_DOWNLOADED];
} else if (pePiece.isRequested(i)) {
color = colors[COLOR_REQUESTED];
}
gcImage.setBackground(color);
gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, y1);
if (isCached[i]) {
gcImage.setBackground(colors[COLOR_INCACHE]);
gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, 3);
}
drawnWidth += nextWidth;
}
gcImage.dispose();
Image oldImage = null;
Graphic graphic = cell.getGraphic();
if (graphic instanceof UISWTGraphic) {
oldImage = ((UISWTGraphic)graphic).getImage();
}
if (cell instanceof TableCellSWT) {
((TableCellSWT) cell).setGraphic(image);
} else {
cell.setGraphic(new UISWTGraphicImpl(image));
}
if (oldImage != null && !oldImage.isDisposed())
oldImage.dispose();
gcImage.dispose();
}
}