<?php
/********************************************************************************
 * (c)1337 aheadware.com - All rights reserved
 ********************************************************************************/
/**
 * Class Francis_Core_Autoloader
 *
 * Static autoloader class
 *
 * Usage:
 * Francis_Core_Autoloader::attachLocator( ... );
 * Francis_Core_Autoloader::init();
 *
 */
class Francis_Core_Autoloader {

    // Holder of various locators
    protected static $locators = array();

    // Allow only static usage of this class
    private function __construct() {}
    private function __clone() {}

    /**
     * Init autoloading mechanism
     */
    final public static function init() {
        spl_autoload_register( array( 'Francis_Core_Autoloader', 'autoload'), true, true );
    }

    /**
     * Attach given locator
     *
     * @param Francis_Core_Locator $locator
     */
    final public static function attachLocator( Francis_Core_Locator $locator ) {
        self::$locators[ $locator->prefix ] = $locator;
    }

    /**
     * Detach locator by given prefix
     *
     * @param string $prefix
     */
    final public static function detachLocator( $prefix ) {
        if ( isset( self::$locators[ $prefix ] ) ) {
            unset( self::$locators[ $prefix ] );
        }
    }

    /**
     * Autoload function called by PHP
     *
     * @param string $classname
     */
    final public static function autoload( $classname ) {
        self::load( $classname );
    }

    /**
     * Loads given classname by appropriate locator
     *
     * @param string $classname
     * @return bool
     */
    final private static function load( $classname ) {
        $parts = explode( '_', $classname );
        if ( 0 < count( $parts ) && isset( self::$locators[ $parts[0] ] ) ) {
            $path = self::$locators[ $parts[ 0 ] ]->resolvePath( $classname );
            if ( file_exists( $path ) ) {
                require_once $path;
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}