﻿/* ==============================================
    Модуль для работы с функциями компилятора
        (компиляция,
         выполнение,
         ввод-вывод,
         завершение программы)
   ============================================== */


// ************************************************************** Вспомогательные объекты ***********************************************************

// "Получатель" данных для вывода
function OutputGetter() {
    // ---------- Поля
    this.output_buffer = new Array();           // Буфер данных
    this.response_number = 0;                   // Наибольший номер правильно обработанного пакета
    this.requests_amount = 0;                   // Число отправленых на данные запросов
    this.responses_amount = 0;                  // Число полученных ответов
    this.toFinish = false;                      // Пакет с признаком конца уже получен
    this.lastRequestHasExecutionError = false;  // Если в последнем пакете есть ошибка исполнения
    
    // ---------- Методы
    this.incReqAmount = OutputGetter_incReqAmount;                      // Увеличить на один число запросов
    this.incRespAmount = OutputGetter_incRespAmount;                    // Увеличить на один число ответов
    this.incRespNumber = OutputGetter_incRespNumber;                    // Увеличить на один номер последнего обработанного ответа
    this.lastResponse = OutputGetter_lastResponse;                      // Взять последний ответ
    this.lastResponseToNull = OutputGetter_lastResponseToNull;          // Последний полученный ответ в буфере сбросить в null
    this.outputHasFinished = OutputGetter_outputHasFinished;            // Закончен ли прием вывода
    this.setFinishState = OutputGetter_setFinishState;                  // Установить ключи завершения вывода
}

// ------------------------------ Методы
// Увеличить на один число запросов
function OutputGetter_incReqAmount(){
    ++this.requests_amount;
}
// Увеличить на один число ответов
function OutputGetter_incRespAmount(){
    ++this.responses_amount;
}
// Увеличить на один номер последнего обработанного ответа
function OutputGetter_incRespNumber(){
    ++this.response_number;
}
// Взять последний ответ
function OutputGetter_lastResponse(){
    return this.output_buffer[this.response_number];
}
// Последний полученный ответ в буфере сбросить в null
function OutputGetter_lastResponseToNull(){
    this.output_buffer[this.response_number] = null;
}
// Закончен ли прием вывода
function OutputGetter_outputHasFinished(){
    return this.toFinish
        && (this.requests_amount <= this.responses_amount);
}
// Установить ключи завершения вывода
function OutputGetter_setFinishState(isExecutionError){
    this.toFinish = true;
    this.lastRequestHasExecutionError  = isExecutionError;
}

// *************************************************************** Глобальные константы *************************************************************

var interv;
var sock_conn = false;
var in_enter = false;
// таймер отправления инфо о графических событиях
var eventsSend;
// прослушиваются ли графические события
var listenGraphEvents = false;
// Используется ли в задании задачник
var usePt4Web = false;

// Приемщик данных для вывода
var output_getter = new OutputGetter();
// Надо ли обрабатывать содержимое вывода, как графическую команду
var outputAsCanvasGraphCmd = false;

var pt4Content = "";                // Содержимое страницы задачника
var twoPT4Contents = false;         // Есть ли второй вариант
var pt4ContentLong = "";            // Второе содержимое задачника
var shortPT4ContentIsLoaded = true; // Загружен короткий вариант    
    

// Позиция — строка и столбец
function Position(line, column) {
    this.line = line;
    this.column = column;
}

// Выхватывает из строки ошибки компиляции номер
// строки, в которой произошла ошибка
function GetPositionOfCompilerError(errorStr) {
    var firstLineInd = errorStr.indexOf("(") + 1;
    var delimInd = errorStr.indexOf(",");
    var lastColumnInd = errorStr.indexOf(")");
    
    var line = errorStr.slice(firstLineInd, delimInd);
    var column = errorStr.slice(delimInd + 1, lastColumnInd);
    var result = new Position(line, column);
    return result;
}

// Выхватывает из строки ошибки выполнения номер
// строки, в которой произошла ошибка
function GetLineOfExecutionError(errorStr) {
    var firstInd = errorStr.indexOf("строка ") + 7;
    var lastInd = errorStr.indexOf("\n");
    
    var result = errorStr.slice(firstInd, lastInd-1);
    return result;
}

// Выхватывает имя файла, в котором произошла ошибка
function GetErrorFileName(errorStr){
    var firstInd = errorStr.lastIndexOf("\\") + 1;
    var lastInd = errorStr.lastIndexOf(":");
    
    var result = errorStr.slice(firstInd, lastInd);
    return result;
}

// Выхватывает имя файла, в котором произошла ошибка компиляции
function GetFileNameOfCompilerError(errorStr){
    var endNameInd = errorStr.indexOf("(");
    return errorStr.substr(0, endNameInd);
}

// ************************************************************ Управление вводом-выводом ***********************************************************


// ------------------------------------------------------ Остатки старой графики
function CutOneGraphCommandFrom(text) {
    var grCh = '@'; // символ ограничивающий графкоманду
    var R = [];
    R[0] = text;
    R[1] = '';
    var txt = '';
    var grtxt = '';
    var t1 = '';
    var t2 = text;
    var p1;
    if (t2.indexOf(grCh) != -1) {
        p1 = t2.indexOf(grCh);
        // разделяем строку по p1
        t1 = text.substring(0, p1);
        t2 = text.substring(p1 + 1);
        p2 = t2.indexOf(grCh);
        grtxt = grtxt + t2.substring(0, p2);
        t2 = t2.substring(p2 + 1);
        txt = txt + t1 + t2;
        R[0] = txt; R[1] = grtxt;
    }
    return R;
}

// извлекает графкоманды из text 
// Result[0] оставшийся текст
// Result[1] графкоманды
function extractGraphCommands(text) {
    var result = [];
    var r;
    r = CutOneGraphCommandFrom(text);
    var grcmds = r[1]; // графкоманды
    var txt = r[0];    // остальной текст
    while (r[1] != '') {
        r = CutOneGraphCommandFrom(txt);
        grcmds = grcmds + r[1];
        txt = r[0];
    }
    result[0] = txt; result[1] = grcmds;
    return result;
}


var grWin;
var grCmdBuff = '';
function processText(txt){
   // извлекаем графкоманды из txt
    var resExtract=extractGraphCommands(txt);
    var text=resExtract[0];
    
    var grCommands=resExtract[1];
    // если графокно не создано, то открыть его
    if (grCommands !='' && !grWin) {grWin= open("grClientCode.htm");}
    
    // пишем графкоманду
    //if (grCommands !='') {addCmd(grCommands); alert('to grWin->'+grCommands+' read:'+readCmd());}
    if (grCommands != '') {
        // добавляем графкоманду во временный буфер
        grCmdBuff = grCmdBuff + grCommands;
    }
 // возвращаем оставшийся текст   
 return text;   
}
// ------------------------------------------------------



// Отправляет в поток ввода графическую команду cmd
function SendGraphCmd(cmd){//alert(cmd);
    currentEventCode = 0;
    eventsBuffer = eventsBuffer.slice(currentEventsBufferSize);               // Сбрасываем буфер
    if (compId != null) {
        if (!ProgramIsRunned)
            return;
        PageMethods.SendReadString(compId, cmd, SendGraphCmd_CallBack);
    }
}
// Обратный вызов отправки графичекой команды
function SendGraphCmd_CallBack() {
}

var IORequestCount = 0;
var IOAnswersCount = 0;

function GetProcessOutput() {
    //alert(PageMethods.prototype.GetMessageOfTheDay);
    if (compId != null) {
        output_getter.incReqAmount();
        ++IORequestCount;
        PageMethods.GetProcessOutput(compId, GetProcessOutput_CallBack);   
    }
}

function SendReadString(s) {
    //StopReadOutput();
    if (!ProgramIsRunned)
        return;
    if (compId != null) {
        ++IORequestCount;
        PageMethods.SendReadString(compId, s, SendReadString_CallBack);
    }
}

function SendReadString_CallBack(responce) {
    ++IOAnswersCount;
    if (responce == null) {
        OnStopProgramm("incorrect");
        InformAboutError(EXECUTION_SERVER_ERROR);
    }
    //GetProcessOutput();
    //StartReadOutput();
}

// Ввод данных в поле ввода
function enter_data() {
    el3 = $get("EnterEdit");
    var data = el3.value
    WriteTextToOutputBox(data + "\n", "output");
    $get("StatusImage").src = "images/isRunning.gif";
    SendReadString(data);
    HideEnterString();
}

function HideEnterString() {
    enterBlockOn = false;   // блок ввода спрятан
    //ResizeErrorsAndEditsTextBoxHeight();
    
    statusEl = $get("StatusLabel");
    statusEl.innerHTML = isRunning;
    //el1.style.visibility = "hidden";
    el2 = $get("EnterLabel");
    el2.style.display = "none";
    el4 = $get("EnterEdit");
    el4.style.display = "none";
    el3 = $get("EnterButton");
    el3.style.display = "none";
    el4.value = "";
    el5 = $get("StopButton");
    el5.style.display = "none";
}

function check_for_enter(e) {
    evt = e || window.event || Event;
    if (evt.keyCode == 13) {
        enter_data();
        return false;
    }
    in_enter = true;
}

function sendCmdFromBuffer() {
    //alert('sendCmd');
    // переписываем часть буфера в cookie, если оно свободно
    var cookieTxt = readCmd();
    var cookieLen = cookieTxt.length;

    // если cookie свободна  
    if (cookieLen == 0) {
        // берем из буфера порцию
        var p1 = 2000;
        //if (p1>grCmdBuff.length-1) p1=grCmdBuff.length-1;
        var s3 = grCmdBuff.substring(p1);
        var p3 = s3.indexOf('/');
        var pos = p1 + p3;
        if (p3 == -1) pos = grCmdBuff.length;
        var s1 = grCmdBuff.substring(0, pos); // прорция
        var s2 = grCmdBuff.substring(pos);
        //if (grCmdBuff != '')  alert('s1='+s1+' \n\n s2='+s2);
        addCmd(s1);
        grCmdBuff = s2;
    }
}

// Вывод данных text содержания content (ошибки компиляции или данные для вывода)
function WriteTextToOutputBox(text, content) {
    var resultTab = $find("ResultTabContainer");
    if (content == "errors") {
        el = $get("ResultTabContainer_ErrorsTabPanel_ErrorsTextBox");
        resultTab.set_activeTabIndex(1);
    }
    else {  // это данные для вывода
        el = $get("ResultTabContainer_OutputTabPanel_ResultTextBox");
        resultTab.set_activeTabIndex(0);
    }            
    el.value = el.value + text;
}

function ShowReadString() {
    statusEl = $get("StatusLabel");
    el1 = $get("EnterLabel");
    el3 = $get("EnterButton");
    el2 = $get("EnterEdit");
    el4 = $get("StopButton");
    $get("StatusImage").src = "images/enterWaiting.gif";    // смена статус-картинки на ожидание
    
    enterBlockOn = true;        // блок ввода открыт
    ResizeErrorsAndEditsTextBoxHeight();
    statusEl.innerHTML += enterWaiting;
    el1.style.display = "inline";
    el2.style.display = "inline";
    el3.style.display = "inline";
    el4.style.display = "inline";
    el2.focus();
}
function GetProcessOutput_CallBack2(exited, read_request, number, output) {
    var obj = { exited: exited, readrequest: read_request, output: output, request_number: number };
    //alert(obj.output);
    GetProcessOutput_CallBack(obj);
    //document.getElementById("silverlightControlHost").Content.MainPage.ContinueReading();
}

function GetProcessOutput_CallBack(response) {
    ++IOAnswersCount;
    //sendCmdFromBuffer();
    output_getter.incRespAmount();                      // Увеличили счетчик полученных ответов
    if (response == null) {
        /*StopReadOutput();
        OnStopProgramm();*/
        if (output_getter.outputHasFinished()) {
            FinishOutput();
        }
        else {
            OnStopProgramm("incorrect");
            InformAboutError(EXECUTION_SERVER_ERROR);
        }
        return;
        //InformAboutWarning(processExpiredError);
        //return;
    }
    
    isExecutionError = false;
    var obj = response; //eval("(" + response + ")");
    // выхватываем графкоманды   
    //obj.output = processText(obj.output);
    if (obj.output != "" && obj.output != null) {
        // если принятый пакет не совпадает с ожидающимся
        if (!sock_conn && response.request_number != output_getter.response_number) {
            output_getter.output_buffer[response.request_number] = response;
            CheckExited(obj);
            //WriteTextToOutputBox("Write response " + response.request_number + "\r\n", "output");
            return;
        }
        if (!ProcessExecutionError(obj.output)){
            if (outputAsCanvasGraphCmd)                     // Обрабатываем данные вывода как графические команды Canvas
                ProcessCanvasGraphCmd(obj.output);          // В файле canvasUse.js
            else if (!usePt4Web)
                WriteTextToOutputBox(obj.output, "output");
            else        
                ProcessPt4WebContent(obj.output);           // Обрабатываем как содержимое задачника   
        }  
        output_getter.incRespNumber();                      // Один пакет обработали, берем следующий ожидаемый номер
        // пока не дошли до очередной "дырки" в буфере приема
        while (output_getter.lastResponse()) {
            var obj2 = output_getter.lastResponse();
            output_getter.lastResponseToNull();
            if (!ProcessExecutionError(obj2.output))
                if (outputAsCanvasGraphCmd)                 // Обрабатываем данные вывода как графические команды Canvas
                    ProcessCanvasGraphCmd(obj2.output);
                else if (usePt4Web)
                    ProcessPt4WebContent(obj2.output);                    
                else 
                    WriteTextToOutputBox(obj2.output, "output");
            output_getter.incRespNumber();
        }
    }
    if (CheckExited(obj)) 
        return;
        
    // Если обработали последний пакт, который должны были
    if (output_getter.outputHasFinished()) {
        StopReadOutput();
        FinishOutput();
        return;
    } 
    if (obj.readrequest == "1") {
        if (!listenGraphEvents) 
            ShowReadString();
    }
}

function CheckExited(obj){
    if (obj.exited == "1") {
        StopReadOutput();
        output_getter.setFinishState(isExecutionError);
        if (output_getter.outputHasFinished()) {
            FinishOutput();
            return true;
        }
    }  
    return false; 
}

function FinishOutput(){
    if (sock_conn && silverlightInstalled()) {
        document.getElementById("silverlightControlHost").Content.MainPage.CloseConnection(compId);
        PageMethods.CloseSockets(compId);
        sock_conn = null;
    }
    if (output_getter.lastRequestHasExecutionError)
        OnStopProgramm("executionError");
    else if (usePt4Web)                                 // формирование строки-содержимого задачника завершено
        FinishPt4WebProgram();
    else
        OnStopProgramm();
}
    
// Обрабатывает возможную ошибку выполнения
function ProcessExecutionError(output) {
    var errorInd = output.indexOf(executionErrorBegining);
    if (errorInd == -1)                                     // ошибки нет
        return false;

    InformAboutWarning(executionError);
    pt4WebWindow.hide();
    isExecutionError = true;
    
    var textBeforError = output.slice(0, errorInd);         // если есть текст, который нужно вывести до ошибки,
    if (textBeforError != "")                               // выводим его
        WriteTextToOutputBox(textBeforError, "output");
    
    var errorText = output.slice(errorInd);                 // текст всей ошибки
    var newLine = "\n";
    var newLineInd = errorText.indexOf(newLine);
    var errorNameText = output.slice(errorInd, newLineInd); // строка, содержащая название ошибки
    WriteTextToOutputBox(errorNameText, "output");          // выводим название ошибки
    var newLineSecondInd = errorText.indexOf(newLine, newLineInd + 1);
    
    /* Ищем строку, содержащую имя файла пользователя, в котором
    произошла эта ошибка. Это либо полное имя файла вместе с Users_Data
    либо какая-то другая ошибка (например, вызыванная ProcessRunner'ом.
    Если первое - ищем эту строку, иначе ничего не делаем. */
    var hasNexLine = errorText.indexOf(newLine, newLineInd + 1) != -1;
    var hasFullFileName = errorText.indexOf("Users_Data") != -1;
    if (hasNexLine && hasFullFileName){     
        var strWithLineNumber = errorText.slice(newLineInd + 1, newLineSecondInd + 1);      // строка, содержащая номер
        // строку с ошибкой ищем, в ней будет указание имени файла, то есть путь содержит Users_Data
        while (strWithLineNumber.indexOf("Users_Data") == -1) {
            newLineInd = newLineSecondInd;
            newLineSecondInd = errorText.indexOf(newLine, newLineInd + 1);
            strWithLineNumber = errorText.slice(newLineInd + 1, newLineSecondInd + 1);
        }
        var errorStr = GetLineOfExecutionError(strWithLineNumber);
        executionErrorLineNumber = errorStr;
        
        if (!restrictedMode){
            var errorFileName = GetErrorFileName(strWithLineNumber);
            var fullErrorFileName = errorFileName;
            if (isUser){        // если мы в режиме пользователя, значит есть подкаталоги
                fullErrorFileName = fname_GetFullFileName(runningFilePath, errorFileName);
            }
            userVFB_OnFullFileNameClick(fullErrorFileName, errorFileName); 
        }
        editAreaLoader.goToPosition("SourceCodeTextBox", errorStr, "0");
    }
    return true;
}

// Обрабатывает получение следующей части страницы задачника
function ProcessPt4WebContent(nextPt4PageContent){
    pt4Content += nextPt4PageContent;
}    

function StartReadOutput() {
    //alert(document.mainForm.onsubmit);
    //document.mainForm.onsubmit = "return enter_data()";
    if (!sock_conn)
        interv = setInterval(GetProcessOutput, 300);
    //timer = setInterval( sendCmdFromBuffer,300);
}

function StopReadOutput() {
    //someProcessIsRunning = false;
    //document.mainForm.onsubmit = function(evt) { return true; }
    if (interv)
        clearInterval(interv);
    interv = null;
    //if (grCmdBuff=='') clearInterval(timer);
}


// Очищает табы
function ClearTabs() {
    $get("ResultTabContainer_OutputTabPanel_ResultTextBox").value = ""; // очищение полей вывода
    $get("ResultTabContainer_ErrorsTabPanel_ErrorsTextBox").value = ""; // и вывода ошибок
}


// ****************************************************************** Silverlight *******************************************************************
// Определяет, подключается ли соответствующий модуль
/*function SilverlightIsUsed() {
    var sourceCode = editAreaLoader.getValue(EDIT_AREA_SOURCE_ID);      // текст файла
    var a = "4654";
    var silverlightUnitInd = indexOf(SILVERLIGHT_UNIT);
    if (silverlightUnitInd == -1)                                       // в коде даже не используется имя модуля
        return false;
    
}*/

// ******************************************************************* Компиляция *******************************************************************

var compId;
var goToDownloading = false;            // нужно ли после компиляции переходить к скачиванию файла

// Запуск компиляции программы
// <forDownloading> нужно перейти к процессу скачивания файла после компиляции
function compile_programm(forDownloading) {
    if (someCompilerProcessIsRunning){
        alert(fullCompilerProcessMessage);
        return;
    }
    /*if (ProgramIsRunned)
        return;
    if (ProgramIsCompiled)
        return;*/
    if (forDownloading == true)
        goToDownloading = true;
    else
        goToDownloading = false;
    
    ClearTabs();
    var queryData = new CompilationQueryData("", "");           // Данные запроса
    var ownFile = false;
    if (!restrictedMode){
        var currFileTabID = EAManager.GetCurrFileData().id;
        var currFileData = EAManager.TabIDsHash[currFileTabID];
        // ни одного файла не открыто
        if ((currFileData == undefined) || (currFileData == null)) {
            InformAboutWarning(noOpenedFile);
            return;
        }
        queryData.FileName = fname_GetShortFileName(currFileData.FullFileName);
        queryData.FilePath = fname_GetDirectory(currFileData.FullFileName);
        ownFile = (currFileData.FileOwnerType == FileOwnerTypeEnum.USERDATA) 
            || (currFileData.FileOwnerType == FileOwnerTypeEnum.NEWFILE);
        currentWorkFile = {FullName: currFileData.FullFileName, ShortName: queryData.FileName, 
            Dir: queryData.FilePath, OwnerType: currFileData.FileOwnerType, IsOwn: ownFile };
    }
    else {
        currentWorkFile = {FullName: ""};
    }
    var sourceCode = editAreaLoader.getValue(EDIT_AREA_SOURCE_ID);
    
    InformAboutCompilation();
    ProgramIsCompiled = true;
    someCompilerProcessIsRunning = true;
    fullCompilerProcessMessage = inProcess + ofCompiling;
    /*queryToServer = true;                       // устанавливаем флажок, что отправили запрос на сервер
    answerFromServer = false;
    connectionServerBroken = false;*/
    // Добавляем информацию о запросе в список
    var currQueryID = GenerateGuid();
    NetworkQueryViewer.AddQuery(currQueryID, new QueryInfo(
        QueryTypeEnum.COMPILATION, queryData));
    if (!userActivityIsFixed) {
        userActivityIsFixed = true;
        setActivityCookie();
        PageMethods.CompileProgrammWithUserFixing(currQueryID, sourceCode, !ownFile, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, userIP, CompileProgramm_CallBack);
    }
    else
        PageMethods.CompileProgramm(currQueryID, sourceCode, !ownFile, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, CompileProgramm_CallBack);
}

// Выводит список ошибок компиляции, если таковые имеются,
// или сообщает, что компиляция прошла успешно
function CompileProgramm_CallBack(response) {
    someCompilerProcessIsRunning = false;
    /*queryToServer = false;                       
    answerFromServer = true;                            // подтверждаем получение отклика с сервера*/
    if (!ProcessServerQueryResponse(response)){         // Обрабатываем глобальный ответ
        InformAboutError(COMPILATION_SERVER_ERROR);
        return;
    }
    var respData = GetServerQueryResponseData(response);    // собственно результат выполнения запроса
    compId = respData.comp_id;
    var errors = respData.errors;
    var fileType = respData.fileType;
    if (errors != null && errors != "") {
        ProcessCompilerError(errors);
        OnStopCompileProgramm("incorrect");
    }
    else {
        if (!restrictedMode) {
            currentWorkFile.typeIsKnown = true;
            currentWorkFile.type = ((fileType == "ConsoleApplicaton") || (fileType == "WindowsApplicaton")) ? EXE_FILE : 
                (fileType == "ClassLibrary" ? DLL_FILE : PCU_FILE);
        }
        OnStopCompileProgramm("correct");
        if (goToDownloading)
            DownloadCompiledFile();
    }
}

// Обработка ошибки компиляции
function ProcessCompilerError(errors) {
    if (errors == SERVER_COMPILE_ERROR){
        WriteTextToOutputBox(errors, "errors");
        return;
    }
    if (errors.indexOf("Внутренняя ошибка компилятора") != -1){
        WriteTextToOutputBox(errors, "errors");
        return;
    }
    
    var newLinePos = errors.indexOf("\n");
    errors = errors.slice(0, newLinePos - 1);
    var errorPos = GetPositionOfCompilerError(errors);
    if (!restrictedMode){                                   // переход к ошибкам только для полного режима
        var errorFileName = GetFileNameOfCompilerError(errors);
        var fullErrorFileName = errorFileName;
        if (isUser){        // если мы в режиме пользователя, значит есть подкаталоги
            fullErrorFileName = fname_GetFullFileName(currentWorkFile.Dir, errorFileName);
        }
        userVFB_OnFullFileNameClick(fullErrorFileName, errorFileName);
    }
    else{
        errors = errors.slice(errors.indexOf(":") + 2);
    }
    editAreaLoader.goToPosition("SourceCodeTextBox", errorPos.line, errorPos.column - 1);
    WriteTextToOutputBox(errors, "errors");
}

// Окончание компиляции, статус-сообщение об итогах компиляции
function OnStopCompileProgramm(status) {
    ProgramIsCompiled = false;
    compId = null;
    if (status == "correct") {
        SetStatusLineHidden();
    }
    else {
        InformAboutError(compilationErrors);
    }
}

function silverlightInstalled() {
    //return false;
    return Silverlight.isInstalled("1.0") && (navigator.platform.toLowerCase().indexOf("win") != -1 || navigator.platform.toLowerCase().indexOf("mac") != -1)
}

// ******************************************************************* Выполнение *******************************************************************

// Данные текущего выполняемого файла
var runningFullFileName;
var runningFileName;
var runningFilePath;
var runningIsOwn;

// Запуск программы на выполнение
function run_programm() {
    if (someCompilerProcessIsRunning){
        alert(fullCompilerProcessMessage);
        return;
    }
//    if (ProgramIsCompiled) {
//        //alert("is compiling");
//        return;
//    }
//    if (ProgramIsRunned) return;
    response_number = 0;
    ClearTabs();
    var queryData = new ExecutionQueryData("", "");         // Данные запроса
    isExecutionError = false;
    outputAsCanvasGraphCmd = false;                         // Изначально, файл не считается графическим
    output_buffer = new Array();
    
    if (!restrictedMode){
        var currFileTabID = EAManager.GetCurrFileData().id;
        var currFileData = EAManager.TabIDsHash[currFileTabID];
        // ни одного файла не открыто
        if ((currFileData == undefined) || (currFileData == null)) {
            InformAboutWarning(noOpenedFile);
            return;
        }
        runningFullFileName = currFileData.FullFileName;
        queryData.FileName = fname_GetShortFileName(currFileData.FullFileName);
        runningFileName = queryData.FileName;
        queryData.FilePath = fname_GetDirectory(currFileData.FullFileName);
        runningFilePath = queryData.FilePath;
        runningIsOwn = (currFileData.FileOwnerType == FileOwnerTypeEnum.USERDATA) 
            || (currFileData.FileOwnerType == FileOwnerTypeEnum.NEWFILE);
        currentWorkFile = { FullName: runningFullFileName, ShortName: runningFileName,
            Dir: runningFilePath, OwnerType: currFileData.FileOwnerType, IsOwn: runningIsOwn };
    }
    else {
        currentWorkFile = {FullName: ""};       // в обрезанном режиме работаем без имени файла
    }
    var sourceCode = editAreaLoader.getValue(EDIT_AREA_SOURCE_ID);
    
    ProgramIsRunned = true;
    someCompilerProcessIsRunning = true;
    fullCompilerProcessMessage = inProcess + ofExecuting;
    $get("EnterEdit").value = ""; 
    // Добавляем информацию о запросе в список
    var currQueryID = GenerateGuid();
    NetworkQueryViewer.AddQuery(currQueryID, new QueryInfo(
        QueryTypeEnum.EXECUTION, queryData));
//    queryToServer = true;                       // устанавливаем флажок, что отправили запрос на сервер
//    answerFromServer = false;
//    connectionServerBroken = false;
    InformAboutExecution();  
    if (!userActivityIsFixed) {
        userActivityIsFixed = true;
        setActivityCookie();
        PageMethods.RunProgrammWithUserFixing(currQueryID, sourceCode, !runningIsOwn, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, userIP, silverlightInstalled(), RunProgramm_CallBack);
    }
    else {
        PageMethods.RunProgramm(currQueryID, sourceCode, !runningIsOwn, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, silverlightInstalled(), RunProgramm_CallBack);
    }
}

// ------------------------------------
function RunProgramm_CallBack(response) {
    /*if (connectionServerBroken){                // вдруг на этот момент соединение уже разорвано
        if (compId != null)
            PageMethods.StopProgramm(compId);
        return;
    }
    queryToServer = false;                       
    answerFromServer = true;                    // подтверждаем получение отклика с сервера*/
    if (!ProcessServerQueryResponse(response)){             // Обрабатываем глобальный ответ
        InformAboutError(EXECUTION_SERVER_ERROR);
        someCompilerProcessIsRunning = false;
        ProgramIsRunned = false;
        return;
    }
    var response = GetServerQueryResponseData(response);    // собственно результат выполнения запроса
    
    IOAnswersCount = 0;
    IORequestCount = 0;
    
    compId = response.comp_id;
    var errors = response.errors;
    var fileType = response.fileType;
    var graphFileType = response.graphType;
    var unitFileType = response.unitFileType;
    if (errors != null && errors != "") {
        ProcessCompilerError(errors);
        OnStopProgramm("incorrect");
        StopReadOutput();
    }
    else {
        // Модуль невозможно выполнить
        if (fileType == pascalCompiledUnit) {
            OnStopProgramm("correct");
            alert("Невозможно запустить откомпилированный модуль");
            StopReadOutput();
        }
        else if (fileType == classLibrary) {
            OnStopProgramm("correct");
            alert("Невозможно запустить динамическую библиотеку");
            StopReadOutput();
        }
        /*else if (graphFileType == SILVERLIGHT_TYPE){
        // Действия для работы с графики Silverlight
        $get("silverlightControlHost").style.visibility = "visible";
        sendGuidToSL(compId); alert("Ура! Я - клиент!");
            
        var currTitle = editAreaLoader.getCurrFileTitle("SourceCodeTextBox");
        var currTabID = editAreaLoader.getCurrentFile(EDIT_AREA_SOURCE_ID).id;
        var currentFile = File_GetFileByTabID(currTabID);
        currentWorkFile = currentFile;
        sourceFileName = currentFile.fullName;
        someProcessIsRunning = true;
        fullProcessMessage = inProcess + ofExecuting;
        var userDir = (isUser) ? userName : currSessionID;
        PageMethods.ContinueRunGraphProgramm(compId, sourceFileName, isUser, userDir, ContinueRunGraphProgramm_CallBack);
        }*/
        else if (graphFileType == CANVAS_TYPE) {
            // В IE канвас не работает
            if (IE) {
                alert("К сожалению, Internet Explorer не поддерживает графику");
                OnStopProgramm("incorrect");
                SetStatusLineHidden();
                return;
            }
            // Действия для работы с графикой Canvas
            canvasWindow.setTitle(CANVAS_WINDOW_TITLE);
            canvasWindow.show();                        // Открываем графическое окно
            outputAsCanvasGraphCmd = true;              // Теперь будем обрабатывать данные для вывода, как граф. команды
            ClearCanvas();                              // Очищаем окно (В файле canvasUse.js) 
            //draw();             // Проверка работы

            var queryData = new ContinueGraphExecutionQueryData("", "");           // Данные запроса
            if (!restrictedMode) {
                queryData.FileName = runningFileName;
                queryData.FilePath = runningFilePath;
            }
            else {
                queryData.FileName = "PasFileFromRestrictedMode.pas";
            }
            someCompilerProcessIsRunning = true;
            fullCompilerProcessMessage = inProcess + ofExecuting;
            // Добавляем информацию о запросе в список
            var currQueryID = GenerateGuid();
            NetworkQueryViewer.AddQuery(currQueryID, new QueryInfo(
                QueryTypeEnum.CONTINUE_GRAPH_EXECUTION, queryData));
            //sock_conn = document.getElementById("silverlightControlHost").Content.MainPage.SendCompilerId(compId);
            if (silverlightInstalled()) {
                tmpObj = { compId: compId, currQueryID: currQueryID, fileName: queryData.FileName, isUser: isUser, userID: GetUserID(), userDir: queryData.FilePath  };
                document.getElementById("silverlightControlHost").Content.MainPage.SendCompilerId(compId);
            }
            else
                PageMethods.ContinueRunGraphProgramm(currQueryID, compId, !runningIsOwn, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, ContinueRunGraphProgramm_CallBack);
        }
        else if (unitFileType == UnitFileTypeEnum.PT4_WEB) {         // подключен задачник PT4Web
            pt4WebWindow.setTitle(PT4_WINDOW_TITLE);
            pt4WebWindow.show();                        // Открываем графическое окно
            pt4WebWindow.getContent().innerHTML = "";
            usePt4Web = true;

            var queryData = new ContinuePT4ExecutionQueryData("", "");           // Данные запроса
            if (!restrictedMode) {
                queryData.FileName = runningFileName;
                queryData.FilePath = runningFilePath;
            }
            else {
                queryData.FileName = "PasFileFromRestrictedMode.pas";
            }
            someCompilerProcessIsRunning = true;
            fullCompilerProcessMessage = inProcess + ofExecuting;
            // Добавляем информацию о запросе в список
            var currQueryID = GenerateGuid();
            NetworkQueryViewer.AddQuery(currQueryID, new QueryInfo(
                QueryTypeEnum.CONTINUE_PT4_EXECUTION, queryData));
            if (silverlightInstalled()) {
                tmpObj = { compId: compId, currQueryID: currQueryID, fileName: queryData.FileName, isUser: isUser, userID: GetUserID(), userDir: queryData.FilePath  };
                document.getElementById("silverlightControlHost").Content.MainPage.SendCompilerId(compId);
            }
            else
                PageMethods.ContinueRunPT4WebProgramm(currQueryID, compId, !runningIsOwn, queryData.FileName, isUser, GetUserID(), isTeacher, isPupil, queryData.FilePath, ContinueRunPT4WebProgramm_CallBack);
        }
        else {
            if (!silverlightInstalled()) {
                //var sourceCode = editAreaLoader.getValue("SourceCodeTextBox");
                StartReadOutput();
            }
            else {
                var queryData = new ContinueGraphExecutionQueryData("", "");           // Данные запроса
                if (!restrictedMode) {
                    queryData.FileName = runningFileName;
                    queryData.FilePath = runningFilePath;
                }
                else {
                    queryData.FileName = "PasFileFromRestrictedMode.pas";
                }
                someCompilerProcessIsRunning = true;
                fullCompilerProcessMessage = inProcess + ofExecuting;
                var currQueryID = GenerateGuid();
                tmpObj = { compId: compId, currQueryID: currQueryID, fileName: queryData.FileName, isUser: isUser, userID: GetUserID(), userDir: queryData.FilePath  };
                document.getElementById("silverlightControlHost").Content.MainPage.SendCompilerId(compId);
            }
        }
    }
}

var tmpObj;

function Continue_Execution(success) {
    //alert(success);
    if (success) {
        sock_conn = true;
    }
    else {
        sock_conn = false;
    }
    if (usePt4Web)
        PageMethods.ContinueRunPT4WebProgramm(tmpObj.currQueryID, tmpObj.compId, !runningIsOwn, tmpObj.fileName, tmpObj.isUser, tmpObj.userID, isTeacher, isPupil, tmpObj.userDir, ContinueRunPT4WebProgramm_CallBack);
    else if (outputAsCanvasGraphCmd)
        PageMethods.ContinueRunGraphProgramm(tmpObj.currQueryID, tmpObj.compId, !runningIsOwn, tmpObj.fileName, tmpObj.isUser, tmpObj.userID, isTeacher, isPupil, tmpObj.userDir, ContinueRunGraphProgramm_CallBack);
    else
        PageMethods.ContinueRunProgramm(tmpObj.currQueryID, tmpObj.compId, !runningIsOwn, tmpObj.fileName, tmpObj.isUser, tmpObj.userID, isTeacher, isPupil, tmpObj.userDir, ContinueProgrammWithSockets_CallBack);
    tmpObj = null;
}

function ContinueProgrammWithSockets_CallBack(responce) {
    //var sourceCode = editAreaLoader.getValue("SourceCodeTextBox");
    StartReadOutput();
}

// После продолжения выполнения графической программы
function ContinueRunGraphProgramm_CallBack(response){
    /*if (connectionServerBroken){                // вдруг на этот момент соединение уже разорвано
        if (compId != null)
            PageMethods.StopProgramm(compId);
        return;
    }
    queryToServer = false;                       
    answerFromServer = true;*/
    if (!ProcessServerQueryResponse(response)){         // Обрабатываем глобальный ответ
        InformAboutError(EXECUTION_SERVER_ERROR);
        return;
    }
    response = GetServerQueryResponseData(response);    // собственно результат выполнения запроса
    
    compId = response.comp_id;
    var errors = response.errors;
    if (errors != null && errors != "") {
        ProcessCompilerError(errors);
        OnStopProgramm("incorrect");
        StopReadOutput();
    }
    else {
        var sourceCode = editAreaLoader.getValue("SourceCodeTextBox");
        listenGraphEvents = true;
        GraphCmdBuffer = "";
        CanvasEventCmdsTimer = setInterval(CanvasEventCmdsTimerHandler, SEND_EVTS_INTERVAL);
        GraphCmdBufferTimer = setInterval(GraphCmdBufferTimerHandler, PROCESS_CMD_INTERVAL);
        waitNext = true;
        toContinueGraph = true;
        StartReadOutput();
    }
}

// После продолжения выполнения программы с задачником
function ContinueRunPT4WebProgramm_CallBack(response){
    if (!ProcessServerQueryResponse(response)){         // Обрабатываем глобальный ответ
        InformAboutError(EXECUTION_SERVER_ERROR);
        return;
    }
    response = GetServerQueryResponseData(response);    // собственно результат выполнения запроса
    
    compId = response.comp_id;
    var errors = response.errors;
    if (errors != null && errors != "") {
        ProcessCompilerError(errors);
        OnStopProgramm("incorrect");
        StopReadOutput();
    }
    else {
        var sourceCode = editAreaLoader.getValue("SourceCodeTextBox");
        pt4Content = "";                // очистили содержимое окна задачника
        StartReadOutput();
    }
}

function ChangePT4WebWindowContent(){
    if (!twoPT4Contents)
        return;
    var newContent = "<div id='pt4WebDiv' onclick='ChangePT4WebWindowContent();'>" 
        + (shortPT4ContentIsLoaded ? pt4ContentLong : pt4Content )
        + "</div>";
    pt4WebWindow.setSize(100,100);
    pt4WebWindow.getContent().innerHTML = newContent;
    pt4WebWindow.updateWidth();
    pt4WebWindow.updateHeight();
    pt4WebWindow.setSize(pt4WebWindow.width + 20, pt4WebWindow.height + 20);
    shortPT4ContentIsLoaded = !shortPT4ContentIsLoaded;
}

function ProcessPt4ResultContent(pt4WebResultContent){
    if (pt4WebResultContent[0] != '!')
        twoPT4Contents = false;
    else {
        twoPT4Contents = true;  //alert(pt4WebResultContent);
        var lenEndIndex = pt4WebResultContent.indexOf("!", 1);
        var shortContentLenStr = pt4WebResultContent.substring(1, lenEndIndex);
        var shortContentLen = parseInt(shortContentLenStr);
        pt4Content = pt4WebResultContent.substr(lenEndIndex + 1, shortContentLen);
        pt4ContentLong = pt4WebResultContent.substring(lenEndIndex + 1 + shortContentLen);
    }
}

// Заврешение выполнения программы с задачником
function FinishPt4WebProgram() {
    var content = pt4Content;
    ProcessPt4ResultContent(content);
    
    if (twoPT4Contents)
        shortPT4ContentIsLoaded = true;
    var newContent = "<div id='pt4WebDiv' onclick='ChangePT4WebWindowContent();'>" 
        + pt4Content 
        + "</div>";
    pt4WebWindow.setSize(100,100);
    pt4WebWindow.getContent().innerHTML = newContent;
    pt4WebWindow.updateWidth();
    pt4WebWindow.updateHeight();
    pt4WebWindow.setSize(pt4WebWindow.width + 20, pt4WebWindow.height + 20);
    OnStopProgramm();
    //(СТАРОЕ)
    //var userDir = (isUser) ? userName : currSessionID;
    //PageMethods.GetPt4WebHTMLContent(sourceFileName, isUser, userDir, GetPt4WebHTMLContent_CallBack);
}
// (СТАРОЕ) Загружаем содержимое страницы-результата             
function GetPt4WebHTMLContent_CallBack(response){
    /*pt4WebWindow.getContent().innerHTML = response;
    OnStopProgramm();*/
}

function OnStopProgramm(status) {
    StopReadOutput();
    output_getter = new OutputGetter();
    someCompilerProcessIsRunning = false;
    ProgramIsRunned = false;
    if (sock_conn) {
        document.getElementById("silverlightControlHost").Content.MainPage.CloseConnection(compId);
        sock_conn = null;
    }
    canvasWindow.hide();                        // на всякий случай, вдруг это была графическая программа
    //pt4WebWindow.hide();
    listenGraphEvents = false;
    usePt4Web = false;
    clearInterval(CanvasEventCmdsTimer);
    toContinueGraph = false;
    clearInterval(GraphCmdBufferTimer);
    HideEnterString();
    compId = null;
    
    if (status == "incorrect") {
        InformAboutError(compilationErrors);
    }
    else if (status == "executionError") {
        pt4WebWindow.hide();
        InformAboutWarning(executionError);
    }
    else  {
        $get("StatusImage").style.visibility = "hidden";
        if (status == "broken") {
            $get("StatusLabel").innerHTML = hasBroken;
        }
        else {
            $get("StatusLabel").innerHTML = hasFinished;
        }
    }     
    WriteQueryInfo("->: " + IORequestCount.toString() + "; " + "<-: " + IOAnswersCount.toString() + "\n");     
}


// ******************************************************************* Завершение *******************************************************************

function StopProgramm_CallBack(response) {
    if (!ProcessServerQueryResponse(response)){         // Обрабатываем глобальный ответ
        InformAboutError(STOP_PROGRAMM_SERVER_ERROR);
        return;
    }
    response = GetServerQueryResponseData(response);    // собственно результат выполнения запроса;
    OnStopProgramm("broken");
}

// Завершение выполнения программы
function stop_programm() {
    if (!ProgramIsRunned) 
        return;
    StopReadOutput();
    
    /*// проверим, что отклик с сервера возвращался; если нет, обрываем связь
    if (queryToServer && !answerFromServer){
        connectionServerBroken = true;
        OnStopProgramm("broken");
    }
    else */if (compId != null) {
        InformAboutBreaking();
        var queryData = new StopProgrammQueryData();           // Данные запроса
        // Добавляем информацию о запросе в список
        var currQueryID = GenerateGuid();
        NetworkQueryViewer.AddQuery(currQueryID, new QueryInfo(
            QueryTypeEnum.STOP_PROGRAMM, queryData));
        PageMethods.StopProgramm(currQueryID, compId, StopProgramm_CallBack);
    }
}

// Флаг "программа компилируется"
var ProgramIsCompiled = false;
// Флаг "программа выполняется"
var ProgramIsRunned = false;

//setTimeout("_SessionExpired()", 1 * 60 * 1000);

function _SessionExpired() {
    //alert("Сессия истекла. Страница будет обновлена.");
    //location.href = location.href; //"http://pascalabc.net/WDE/";
}


// **************************************************************** Загрузка примеров ***************************************************************

/*// Текущий номер примера
var currSampleNum;

function getSampleCallback(responce) {
    var fileName = sampleLabel + responce.FileName;     // имя файла с пометкой "не сохранен"
    var Source = responce.Source;                       // содержимое файла

    var newFile = {id: newID, title: fileName, text: Source};
    
    parFileName = "\"" + fileName + "\"";
    tabsIDHash[parFileName] = newID;      

    NextFileParams();
    
    // запомнили номер примера
    var parFileName = "\"" + fileName + "\"";
    samplesNumsHashByName[parFileName] = currSampleNum;  
    // запомнили имя примера
    var strI = "\"" + currSampleNum.toString() + "\"";
    samplesNamesHashByNum[strI] = fileName;
    
    editAreaLoader.openFile("SourceCodeTextBox", newFile);
    
    $get("StatusLabel").innerHTML = "";
    $get("StatusImage").style.visibility = "hidden";
}

function ex1(i) {
    var strI = "\"" + i.toString() + "\"";
    if (samplesHashByNum[strI]) {
        var parFileName = "\"" + samplesNamesHashByNum[strI] + "\"";
        var specFileID = tabsIDHash[parFileName];
        editAreaLoader.switchToFile("SourceCodeTextBox", specFileID);
        return;
    }
    
    samplesHashByNum[strI] = true;   // запомнили, что пример открыт
    currSampleNum = i;
    
    var statusImg = $get("StatusImage");  
    var statusLabel = $get("StatusLabel");
    
    statusLabel.style.color = "#555555";
    statusLabel.innerHTML = sampleIsLoading;
    statusImg.src = "images/waiting.gif";
    statusImg.style.visibility = "visible";
    PageMethods.getSample(i, getSampleCallback);
}*/
