/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 23-Oct-2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package uk.ac.ic.doc.kevlar.core.framework;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import uk.ac.ic.doc.kevlar.api.programs.arguments.IArgumentModel;
import uk.ac.ic.doc.kevlar.api.programs.returnValues.IReturnModel;
import uk.ac.ic.doc.kevlar.core.framework.internal.IProgram;
import uk.ac.ic.doc.kevlar.core.framework.internal.loaders.ILoader;
import uk.ac.ic.doc.kevlar.core.framework.internal.loaders.IProgramLoader;
import uk.ac.ic.doc.kevlar.core.framework.internal.loaders.LoaderProvider;
import uk.ac.ic.doc.kevlar.publicInterfaces.IProgramDescription;

/**
 * @author Steve Zymler
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ProgramRepository implements IProgramRepository 
{		
	private Map<IProgramID, IProgram> mapIDtoProgram ;		
	private long nextid = 0 ;
	
	public ProgramRepository()
	{
		mapIDtoProgram = new HashMap<IProgramID, IProgram>();		
			
		LoaderProvider.getLoader().waitTillStable();
		
		
	}
	
	public synchronized SortedSet<IProgramIDDescription> getProgramDescriptions() 
	{	
		SortedSet<IProgramIDDescription> progDescSet = new TreeSet<IProgramIDDescription>(new Comparator<IProgramIDDescription>(){

            public int compare(IProgramIDDescription arg0, IProgramIDDescription arg1)
            {
                return arg0.getFriendlyName().compareTo(arg1.getFriendlyName());
            }
		    
		});
			
		for( Map.Entry<IProgramID, IProgram> entry : mapIDtoProgram.entrySet() )
		{									
			IProgramID progID = entry.getKey();
			IProgram prog = entry.getValue();
			
			IProgramDescription progDesc = prog.getDescription().getProgramDescription() ;
			progDescSet.add( new ProgramIDDescription( progID, prog.getCanonicalName(), progDesc ) );						
		}
			 
		return progDescSet;
	}
	
	public synchronized void rehashPrograms()
	{
		ILoader loader = LoaderProvider.getLoader();
		IProgramLoader progLoader = loader.getProgramLoader();
		Set<IProgram> loadedProgSet = progLoader.getPrograms();
		
		loadedProgSet.removeAll( mapIDtoProgram.values() );
		
		for( IProgram prog : loadedProgSet )
		{
			IProgramID progID = new ProgramID( nextid );
			mapIDtoProgram.put( progID, prog );
			++nextid;
		}											
	}
	
	public synchronized IArgumentModel getProgramArgument(IProgramID id) 
	{
		IProgram program = mapIDtoProgram.get(id);				
		return program.getArgumentModelProvider().getArgumentModel();
	}
	
	public synchronized IProgramDescription getProgramDescription(IProgramID id) 
	{
		IProgram program = mapIDtoProgram.get(id);				
		return program.getDescription().getProgramDescription();
	}	
   
	public synchronized IReturnModel getReturnModel(IProgramID id)
	{
		IProgram program = mapIDtoProgram.get(id);				
		return program.getReturnModelProvider().getReturnModel();
	}
	
    public synchronized IProgram getProgram(IProgramID id) 
    {
        return mapIDtoProgram.get(id);        
    }		
    
    
}
