/*

CLASS {Text_file|_Gcc},
UNTESTED, STOPPING, NATIVE, BITWISE, DEPRECATED('{File_stream}') :

IMPORT: {System_functions}, {String_functions}, {File_path} ;

NATIVE: "#include <iostream>" .
NATIVE: "#include <fstream>" .


STR Path|_to_text_file, INIT

{String_functions}.{encoding} Encoding

METHOD Load|_strings_appending_to_Lines(
STR Lines|_to_load[]) ==> BOOL
    :
    CASE !Path.Exists ? ==> ;
    RESULT = do_Load(Path, Lines[], Encoding) 
    STR f|irst_line = Lines[0]
    //INT f0|_ordinal = f[0].Ord
    //INT f1|_ordinal = f[1].Ord
    //INT f2|_ordinal = f[2].Ord
    //CASE f0 == 0xEF && f1 == 0xBB && f2 == 0xBF || (
    //     f0 == 0x3F && f1 == 0xBB && f2 == 0x57)
    //     ?
    //     Lines[0] = f[3 TO *] ;
    -------------------------------- 'remove BOM'
	INT ff|irst_character = f[0].Ord
	CASE ff == 0xFEFF ?
	     Lines[0] = f[1 TO *] ;
	-------------------------------- 'remove anbiguous #NL at end of lines'
    FOR s IN Lines[] :
        CASE s[*] !IN #NL ? CONTINUE s ;
        FOR i IN [s.Len-1 DOWNTO 0] :
            CASE s[i] !IN #NL ? 
                 Lines[s.Index] = s[0 TO i]
                 BREAK i ;
        ;
    ; .

FUNCTION Text_load|_first_clear_lines( STR Path|_file, STR Lines|_array[] ) :
    Lines[].Clear
    temp|_loader = {Text_file}(Path = Path)
    NONE = temp.Load(Lines[]) .

FUN do_Load|_strings(
STR Path|_to_text_file,
STR Lines|_to_load[],
{encoding} Encoding) ==> BOOL, NATIVE : @
    "    try {"
    "        std::ifstream fs(X_Path,"
    "        std::ios::in | std::ios::binary);"
    "        if (!fs) return false;"
    "        std:: string x;"
    "        while (!fs.eof())"
    "        {"
    "           std::getline(fs, x);"
    "           X_Lines->Add(x);"
    "        }"
    "        fs.close();"
    "        RESULT = true;"
    "    }"
    "    catch (std::exception& e) {"
    "        AL4_system::Any_exception(e);"
    "        RESULT = false;"
    "    }" .

FUNCTION Text_save( STR Path|_file, STR Lines|_array[] ) :
    temp|_saver = {Text_file}(Path = Path)
    NONE = temp.Save(Lines[]) .

FUN Unix_text_save( STR Path|_file, STR Lines|_array[] ) :
    temp|_saver = {Text_file}(Path = Path)
    temp.Line_end = #10
    NONE = temp.Save(Lines[]) .
    
FUN Unicode_save( STR Path|_file, STR Lines|_array[] ) :
temp|_saver = {Text_file}(Path = Path, Encoding= 'UTF8')
NONE = temp.Save(Lines[]) .


    
METHOD Save|_strings(STR Lines|_to_save[]) ==> BOOL :
	//DEBUG: << "called Save, Path=[" Path "]" ;
    Stop_if_test(Path)
    //DEBUG: << "+" ;
    STR dir|ectory = Path.Extract_path
    //DEBUG: << "!+ dir=" dir #NL ;
	CASE !dir.Dir_exists ?
	     //DEBUG: << "- dir not exists, try create "#NL ;
	     dir.Create_dir ;
    //DEBUG: << "!created dir: " dir #NL ;
    CASE !dir.Dir_exists ? ==> ;
    RESULT = do_save(Path, Lines[], Line_end, Encoding == 'UTF8') .

STR Line_end|ing_sequence = #13#10

FUN do_save|_strings(
STR Path|_of_file, STR Lines|_to_save[],
STR Line_end, BOOL Is_utf8|_encoding) ==> BOOL, NATIVE :
    NATIVE @
    "    try {"
    "#ifdef _MSC_VER"
    "    int siz = MultiByteToWideChar(CP_UTF8, 0, "
    "        X_Path.c_str(), X_Path.length(), NULL, 0);"
    "    std::wstring w;"
    "	 w.reserve(siz);"
    "	 for (int i = 0; i < siz; i++) w += '_';"
    "    MultiByteToWideChar(CP_UTF8, 0, X_Path.c_str(), "
    "           X_Path.length(), &w[0], siz);"
    "       std::fstream fs(w.c_str(),"
    "             std::ios_base::out"
    "           | std::ios_base::trunc "
    "           | std::ios_base::binary);"
    "#else"
    "       std::fstream fs(X_Path,"
    "             std::ios_base::out"
    "           | std::ios_base::trunc "
    "           | std::ios_base::binary);"
    "#endif"
    "        if (!fs.is_open()) return false;"
    "        if (X_Is_utf8)"
    "        {"
    "           int size_b = 4096;"
    "           byte* b = (byte*)malloc(size_b);"
    "           for(int i = 0; i < X_Lines->Count(); i++)"
    "           {"
    "               std::string s = X_Lines->get(i);"
    "           #ifdef MSWINDOWS"
    "               std::wstring WS(s.begin(), s.end());"
    "               if (WS.length() == 0)"
    "               {"
    "                   fs << X_Line_end;"
    "                   continue;"
    "               }"
    "               int size = WideCharToMultiByte(CP_UTF8, 0,"
    "                   &WS[0], WS.length(), NULL, 0, NULL, NULL);"
    "               if (size == 0)"
    "               {"
    "                   fs << X_Line_end;"
    "                   continue;"
    "               }"
    "               if (size_b <= size)"
    "               {"
    "                   size_b = size + 1;"
    "                   free(b);"
    "                   b = (byte*)malloc(size_b);"
    "               }"
    "               WideCharToMultiByte(CP_UTF8, 0, &WS[0],"
    "                   WS.length(), (LPSTR)&b[0], size, NULL, NULL);"
    "               b[size] = 0;"
    "               fs << (char*)&b[0] << X_Line_end;"
    "           #else"
    "               fs << s << X_Line_end;"
    "           #endif"
    "           }"
    "           free(b);"
    "        }"
    "        else"
    "           for(int i = 0; i < X_Lines->Count(); i++)"
    "           {"
    "               std::string s = X_Lines->get(i);"
    "               //while (s.length() > 0 && s[s.length()-1] == '\r')"
    "               //    s = s.substr(0, s.length()-1);"
    "               fs << s << X_Line_end;"
    "           }"
    "        fs.close();"
    "        RESULT = true;"
    "    }"
    "    catch (std::exception& e) {"
    "        AL4_system::Any_exception(e);"
    "        RESULT = false;"
    "    }" .
        
END
*/

