/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.viewers.deferred;



/**
 * Allows a table to be accessed from a background thread. Provides a table-like public 
 * interface that can accessed from a background thread. As updates arrive from the 
 * background thread, it batches and schedules updates to the real table in the UI thread. 
 * This class can be used with any widget that can be wrapped in the 
 * <code>AbstractVirtualTable</code> interface.  
 * 
 * @since 3.1
 */
/* package */ final class ConcurrentTableUpdator {
	/**
	 * Wrapper for the real table. May only be accessed in the UI thread.
	 */
    private AbstractVirtualTable table;
    
    /**
     * The array of objects that have been sent to the UI. Elements are null
     * if they either haven't been sent yet or have been scheduled for clear. 
     * Maps indices onto elements.
     */
    private Object[] sentObjects = new Object[0];
    
    /**
     * Map of elements to object indices (inverse of the knownObjects array)
     */
    private IntHashMap knownIndices = new IntHashMap();
    
    /**
     * Contains all known objects that have been sent here from the background
     * thread.
     */
    private Object[] knownObjects = new Object[0];
    
    // Minimum length for the pendingFlushes stack
    private static final int MIN_FLUSHLENGTH = 64;
    
    /**
     * Array of element indices. Contains elements scheduled to be
     * cleared. Only the beginning of the array is used. The number
     * of used elements is stored in lastClear
     */
    private int[] pendingClears = new int[MIN_FLUSHLENGTH];
    
    /**
     * Number of pending clears in the pendingClears array (this is normally
     * used instead of pendingClears.length since the 
     * pendingClears array is usually larger than the actual number of pending
     * clears) 
     */
    private int lastClear = 0;
    
    /**
     * Last known visible range
     */    
    private volatile Range lastRange = new Range(0,0);
    
    /**
     * True iff a UI update has been scheduled
     */
    private volatile boolean updateScheduled;
    
    /**
     * True iff this object has been disposed
     */
    private volatile boolean disposed = false;
    
    /**
     * Object that holds a start index and length. Allows
     * the visible range to be returned as an atomic operation.
     */
    public final static class Range {
        int start = 0;
        int length = 0;
        
        public Range(int s, int l) {
            start = s;
            length = l;
        }
    }
    
    /**
     * Runnable that can be posted with an asyncExec to schedule
     * an update to the real table.  
     */
    Runnable uiRunnable = new Runnable() {
        public void run() {
            updateScheduled = false;
            if(!table.getControl().isDisposed())
            	updateTable();
        }
    };
    
    /**
     * Creates a new table updator
     * 
     * @param table real table to update
     */
    public ConcurrentTableUpdator(AbstractVirtualTable table) {
        this.table = table;
    }
    
    /**
     * Cleans up the updator object (but not the table itself).
     */
    public void dispose() {
    	disposed = true;
    }
    
    /**
     * True iff this object has been disposed. 
     * 
     * @return true iff dispose() has been called
     */
    public boolean isDisposed() {
    	return disposed;
    }
    
    /**
     * Returns the currently visible range
     * 
     * @return the currently visible range
     */
    public Range getVisibleRange() {
    	return lastRange;
    }
    
    /**
     * Marks the given object as dirty. Will cause it to be cleared
     * in the table. 
     * 
     * @param toFlush
     */
    public void clear(Object toFlush) {
        synchronized(this) {
            int currentIdx = knownIndices.get(toFlush, -1);

            // If we've never heard of this object, bail out.
            if (currentIdx == -1) {
                return;
            }

            pushClear(currentIdx);
        }
        
    }
    
    /**
     * Sets the size of the table. Called from a background thread.
     * 
     * @param newTotal
     */
    public void setTotalItems(int newTotal) {
        synchronized (this) {
            if (newTotal != knownObjects.length) {
                if (newTotal < knownObjects.length) {
                    // Flush any objects that are being removed as a result of the resize
                    for (int i = newTotal; i < knownObjects.length; i++) {
                        Object toFlush = knownObjects[i];
                        
                        if (toFlush != null) {
                        	knownIndices.remove(toFlush);
                        }
                    }
                }
                
                int minSize = Math.min(knownObjects.length, newTotal);
                
	            Object[] newKnownObjects = new Object[newTotal];
	            System.arraycopy(knownObjects, 0, newKnownObjects, 0, minSize);
	            knownObjects = newKnownObjects;
	            	            
	            scheduleUIUpdate();
            }
        }
    }
    
    /**
     * Pushes an index onto the clear stack
     * 
     * @param toClear row to clear
     */
    private void pushClear(int toClear) {
        
    	// If beyond the end of the table
    	if (toClear >= sentObjects.length) {
    		return;
    	}
    	
    	// If already flushed or never sent
        if (sentObjects[toClear] == null) {
        	return;            
        }

        // Mark as flushed
        sentObjects[toClear] = null;
    	
        if (lastClear >= pendingClears.length) {
            int newCapacity = Math.min(MIN_FLUSHLENGTH, lastClear * 2);
            int[] newPendingClears = new int[newCapacity];
            System.arraycopy(pendingClears, 0, newPendingClears, 0, lastClear);
            pendingClears = newPendingClears;
        }
        
        pendingClears[lastClear++] = toClear;
    }
    
    /**
     * Sets the item on the given row to the given value. May be called from a background
     * thread. Schedules a UI update if necessary
     * 
     * @param idx row to change
     * @param value new value for the given row
     */
    public void replace(Object value, int idx) {        
        // Keep the synchronized block as small as possible, since the UI may
        // be waiting on it.
        synchronized(this) {
            Object oldObject = knownObjects[idx];
            
            if (oldObject != value) {
            	if (oldObject != null) {
            		knownIndices.remove(oldObject);
            	}
            	
                knownObjects[idx] = value;
                
            	if (value != null) {
	        		int oldIndex = knownIndices.get(value, -1);
	        		if (oldIndex != -1) {
	        			knownObjects[oldIndex] = null;
	        			pushClear(oldIndex);
	        		}
	        		
	        		knownIndices.put(value, idx);
            	}
                
                pushClear(idx);
                
                scheduleUIUpdate();
            }
        } 
    }

    /**
     * Schedules a UI update. Has no effect if an update has already been
     * scheduled.
     */
    private void scheduleUIUpdate() {
        synchronized(this) {
	        if (!updateScheduled) {
	            updateScheduled = true;
	            if(!table.getControl().isDisposed())
	            	table.getControl().getDisplay().asyncExec(uiRunnable);
	        }
        }
    }
    
    
    /**
     * Called in the UI thread by a SetData callback. Refreshes the
     * table if necessary. Returns true iff a refresh is needed.
     * @param includeIndex the index that should be included in the visible range.
     */
    public void checkVisibleRange(int includeIndex) {
        int start = Math.min(table.getTopIndex() - 1, includeIndex);
        int length = Math.max(table.getVisibleItemCount(), includeIndex - start);
        Range r = lastRange;

    	if (start != r.start || length != r.length) {
    		updateTable();
    	}
    }
    
    /**
     * Updates the table. Sends any unsent items in the visible range to the table,
     * and clears any previously-visible items that have not yet been sent to the table.
     * Must be called from the UI thread.
     */
    private void updateTable() {    	
        
        synchronized(this) {

        	// Resize the table if necessary
	        if (sentObjects.length != knownObjects.length) {
	        	Object[] newSentObjects = new Object[knownObjects.length];
	        	System.arraycopy(newSentObjects, 0, sentObjects, 0, 
	        			Math.min(newSentObjects.length, sentObjects.length));
	        	sentObjects = newSentObjects;
	            table.setItemCount(newSentObjects.length);
	        }

	        // Compute the currently visible range
	        int start = Math.min(table.getTopIndex(), knownObjects.length);
	        int length = Math.min(table.getVisibleItemCount(), knownObjects.length - start);
	        int itemCount = table.getItemCount();
            
        	int oldStart = lastRange.start;
        	int oldLen = lastRange.length;
        	
        	// Store the visible range. Do it BEFORE sending any table.clear calls,
        	// since clearing a visible row will result in a SetData callback which
        	// cause another table update if the visible range is different from
        	// the stored values -- this could cause infinite recursion.
        	lastRange = new Range(start, length);
        	
			// Re-clear any items in the old range that were never filled in
			for(int idx = 0; idx < oldLen; idx++) {
				int row = idx + oldStart;
				
				// If this item is no longer visible
				if (row < itemCount && (row < start || row >= start + length)) {
					
					// Note: if we wanted to be really aggressive about clearing
					// items that are no longer visible, we could clear here unconditionally.
					// The current way of doing things won't clear a row if its contents are
					// up-to-date.
					if (sentObjects[row] == null) {
						table.clear(row);
					}
				}
			}
			
			// Process any pending clears
	        if (lastClear > 0) {
				for (int i = 0; i < lastClear; i++) {
					int row = pendingClears[i];
		
					if (row < sentObjects.length) {
						table.clear(row);
					}
				}
	
				if (pendingClears.length > MIN_FLUSHLENGTH) {
					pendingClears = new int[MIN_FLUSHLENGTH];
				}
				lastClear = 0;
	        }
		    
	        // Send any unsent items in the visible range
	        for (int idx = 0; idx < length; idx++) {
	        	int row = idx + start;
	        	
	        	Object obj = knownObjects[row];
	        	if (obj != null && obj != sentObjects[idx]) {
	        		table.replace(obj, row);
	        		sentObjects[idx] = obj;
	        	}
	        }
	        
        }
    }

	/**
	 * Return the array of all known objects that have been sent here from the background
     * thread.
	 * @return the array of all known objects
	 */
	public Object[] getKnownObjects() {
		return knownObjects;
	}
    
}
