function Shell()
{
    system.addEventListener("onloadSystem", activate);
    system.registerEvent("onbeforeHelp");
    system.registerEvent("onafterHelp");
    system.registerEvent("onchangeReadMode");
    
    var section = "root";
    var shell = {};
    var prompt = "root";
    var readMode = "cli";
    var f = false;
    
    shell["alert"]  = function (arg) { alert(arg) };
    shell["echo"]  = echo;
    shell["help"]  = help;
    shell["exit"]  = exit;
    shell["time"]  = getTime;
    shell["date"]  = getDate;
    shell["counter"]  = function () { system.dispatchEvent("onwriteCounterInfo"); };
    shell["clear"] = function () { system.dispatchEvent("onclear"); };
    shell["title"] = function ( arg ) { document.title = arg };
    shell["prompt"] = function ( arg ) { prompt = arg };
    
    function activate()
    {
        system.addEventListener("onreadline", executor);      
        system.addEventListener("onafterload", changeSection);
        system.addEventListener("onafterunload", returnToRoot);       
        system.addEventListener("onchangeReadMode", changeReadMode);
        system.addEventListener("onafterunload", function () { system.dispatchEvent("onclear"); });
    }
    
    function executor( input )
    {
        if ( readMode == "cui" )
            return;
        var i;
        input = input.replace(/^\s*/, "");
        var tokens = input.split(" ");
        var command = tokens[ 0 ];
        var arg = "";
        if ( tokens.length > 1 )
        {
            arg = tokens[ 1 ];
            for ( i = 2; i<tokens.length; ++i )
                arg += " " + tokens[ i ];
        }
        var event = {};
        event.section = command;
        system.dispatchEvent( "onisExistSection", event );
        if ( shell[ command ] )
        {
            shell[ command ]( arg );
        }
        else
        {
            if ( (event.isExist)&&(section == "root") )
            {
                system.dispatchEvent("onbeforeload", {"name" : command});
                system.dispatchEvent("onload", {"name" : command});
                system.dispatchEvent("onafterload", {"name" : command});                
            }
            else
            {
                if ( section == "root" )
                    system.dispatchEvent("onwrite",
                    "\n  \"" + command + "\" не является командой или названием раздела.\n");
            }
        }
        if ( section == "root" )
            system.dispatchEvent("ontitle", prompt);
        f = false;
    }

    function help()
    {
        system.dispatchEvent("onbeforeHelp");
        system.dispatchEvent("onwrite", "\nобщие команды:\n  counter - информация о посещениях.\n	alert  - вывод сообщений в диалоговом окне.\n	clear  - очистка экрана.\n	date   - вывод даты.\n	echo   - вывод сообщений.\n	exit   - выход из текущего раздела.\n	help   - информация о доступных командах и разделах.\n	prompt - изменение текста в приглашении командной строки.\n	time   - вывод текущего времени.\n	title  - изменение текста в заголовке окна браузера.\n")
        system.dispatchEvent("onafterHelp");
    }
    
    function echo( arg )
    {
        system.dispatchEvent("onwrite", "\n" + arg + "\n");
    }
    
    function changeSection( event )
    {
        section = event.name;
        //alert( section );
    }
    
    function returnToRoot()
    {
        readMode = "cli";
        section = "root";
    }
    
    
    function exit()
    {
        if ( section != "root" )
        {
            system.dispatchEvent("onunload");
            system.dispatchEvent("onafterunload");
            f = true;
        }
    }
    
    function getTime()
    {
        var time = new Date();
        system.dispatchEvent("onwrite",
        "\n    "+time.getHours() + ":"+time.getMinutes()+":"+time.getSeconds ()+"\n");
    }
    
    function getDate()
    {
        var time = new Date();
        system.dispatchEvent("onwrite",
        "\n    "+time.getDate() + "."+time.getMonth()+"."+time.getFullYear()+"\n");    
    }
    
    function changeReadMode( mode )
    {
        if (( mode != "cli" )&&( mode != "cui" ))
            return;
        readMode = mode;
    }
}
