/*
 * Tron.java
 *
 Copyright (C) 2009 fwd
 
   This file is part of I2PSnarkXL.
 
   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, or (at your option)
   any later version.
 
   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
 */

package org.i2p.i2psnarkxl;

import java.util.ArrayList;
import java.util.List;

import net.i2p.I2PAppContext;
import net.i2p.util.Log;

public class Tron extends Thread implements Comparable, Runnable{
    private Log _log = new Log(Tron.class);
    private I2PAppContext _context;
    
    private static final Tron _instance = new Tron();
    public synchronized static final Tron instance() { return _instance; }
    
    public static final List torrentsXL = new ArrayList();
    
    private static boolean stop = true;
    private boolean updateIsRunning = false;
    
    private Thread t;
    
    /** Creates a new instance of Tron */
    private Tron(){
        _context = I2PAppContext.getGlobalContext();
        _log = _context.logManager().getLog(Tron.class);
        //_manager = SnarkManager.instance();
        
        stop = false;
        
    }
    
    
    private synchronized void update(){
        // do something
    }
    /*
     *
     *
     */
    public synchronized void run() {
        assert(t == Thread.currentThread());
        while(!stop) {
            sleep(4000);
            if(torrentsXL.size() > 0 ){
                // do something
                updateIsRunning = true;
                update();
                updateIsRunning = false;
            }
        }
        
    }
    
    private synchronized void sleep(int value){
        try {
            //Random randB = new Random(System.currentTimeMillis());//fwd save CPU power
            //Thread.sleep(value + (Math.abs(randB.nextInt()) % 4000));
            Thread.sleep(value + instance().torrentsXL.size()*50);//sleep 0,5 sec more foreach 10 torrents
        } catch (InterruptedException e2) {
            e2.printStackTrace();
        }
    }
    
    /*
     * toDo recheck if we are in list clientsXL else add this to list
     */
    public synchronized void start() {
        stop = false;
        assert(t == null);
        t = new Thread(this, "Tron Manager");
        t.setDaemon(true);
        t.setPriority(Thread.MIN_PRIORITY);
        t.start();
    }
    
    /*
     * toDo recheck if we are in list clientsXL and remove this from list
     * rem: toDo a removedclientslist to restart them?!
     */
    public synchronized void halt() {
        //toDo implement a user setting or set RuntimeException to false
        if (false) throw new RuntimeException("Tron Manager forced to stop! ( " + " )");
        stop = true;
        
        Thread thread = t;
        if (thread != null)
            thread.interrupt();
    }
    
    /**
     * Two Trons (Torrent jobs) are equal when they have the same Torrenthash
     */
    public boolean equals(Object o) {
        Tron p = (Tron)o;
        //boolean isID = idencode(clientID).equals(p.idencode(clientID));
        //boolean isAddress = destination.calculateHash().toBase64().equals(p.destination.calculateHash().toBase64());
        //boolean isTorrent = metainfo.getInfoHash().equals(p.metainfo.getInfoHash());
        if(true){//isID && isAddress && isTorrent){
            return true;
        }else{
            return false;
        }
    }
    /**
     * Compares the Torrents.
     */
    public int compareTo(Object o) {
        Tron p = (Tron)o;
        //boolean isID = idencode(clientID).equals(p.idencode(clientID));
        //boolean isAddress = destination.calculateHash().toBase64().equals(p.destination.calculateHash().toBase64());
        //boolean isTorrent = metainfo.getInfoHash().equals(p.metainfo.getInfoHash());
        if(true){//isID && isAddress && isTorrent){
            return 0;
        }else{
            return 1;
        }
    }
}