//----------------------------------------------------------------------------//
// file          : plmcsv.imp                                                 //
// description   : classes definition                                         //
//                 CSV files format manipulation                              //
// creation      : 2015/02/09                                                 //
// modification  : 2015/02/09                                                 //
// version       : 1.0                                                        //
// author        : Pierre Le Muzic                                            //
// contributors  :                                                            //
//----------------------------------------------------------------------------//
/*
Licence Terms

// ######################################################################### //
// Copyright (c) 2015, Pierre Le Muzic                                       //
// All rights reserved.                                                      //
// ######################################################################### //
// Redistribution and use in source and binary forms, with or without        //
// modification, are permitted provided that the following conditions        //
// are met:                                                                  //
//                                                                           //
// 1. Redistributions of source code must retain the above copyright notice, //
// this list of conditions and the following disclaimer.                     //
//                                                                           //
// 2. Redistributions in binary form must reproduce the above copyright      //
// notice, this list of conditions and the following disclaimer in the       //
// documentation and/or other materials provided with the distribution.      //
//                                                                           //
// 3. Neither the name of Pierre Le Muzic nor the names of its contributors  //
// may be used to endorse or promote products derived from this software     //
// without specific prior written permission.                                //
// ######################################################################### //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       //
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         //
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   //
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER //
// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  //
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       //
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        //
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    //
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      //
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        //
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              //
// ######################################################################### //

*/

beginPackage PLMCSV_IMP

class Csvlib {
 
        void new(void)
        {
                _datatable = (string []) [];
                _size = 0;
                _csvchar = ",";

        } // new
    
        void delete(void) {}
    
        string getCsvChar () {
        // return the current csv character
                return _csvchar;
        } // getCsvChar
    
        void setCsvChar (string char) {
        // modify the current csv character - default is comma "," - by the new character char
                _csvchar = char;
        } // setCsvChar
    
        int getSize () {
        // return the number of lines in the datatable
                return _datatable.length();
        } // getSize
    
        string [] getData() {
        // return the content of the datatable
                return _datatable;
        } // getData
    
        void clearData (int index) {
        // delete the data from datatable at the specified index
                _datatable.remove(index);     
                _size--;
        } // clearData
   
        void clearAllData (int index1, int index2) {
        // delete all the data in the datatable between the index 1 and the index 2
                int lng = this->getSize();
                _size=0;

                if (index1 > index2) {
                        warning("The second index should be greater than the first one\n");
	                return;
                }

                if (index1 < 0 || index1 > (lng-1)) {
                        warning("The first index is out of range\n");
                        return;
                }
	      
                if (index2 < 0 || index2 > (lng-1)) {
                        warning("The second index is out of range\n");
                        return;
                }
	 
                if (index1==0 && index2==(lng-1)) {
                        _datatable.erase();
                } else {
                        string [] tmp = (string []) [];
                        for (int i=0; i<lng; i++) {
                                if ((i<index1) || (i>index2)) {
                                        tmp.pushBack(_datatable[i]);
                                        _size++;
                                }      
                        }
                        _datatable.erase();
                        for (int k=0; k<tmp.length(); k++) {
                                _datatable.pushBack(tmp[k]);
                        }
                }
    
        } // clearAllData
    
        void appendData (string csvline, string position) {
        // append csv line csvline to the datatable at the specified position (begin or end)
    
                if (position=="begin") {
                        _datatable.pushFront(csvline);
                        _size++; 
                        return;
                }
	  
                if (position=="end") {
                        _datatable.pushBack(csvline);
                        _size++;
                        return;
                }
	 
                warning("Bad string position argument - begin or end is required\n");
                return;
         
        } // appendData
    
        void insertData (string csvline, int insert) {
        // insert csv line csvline in the datatable at index insert
                int lng = this->getSize();
                if (insert<0 || insert > (lng-1)) {
                        warning("The insert argument is out of range\n");
                        return;
                }
                _datatable.insert(insert, csvline);
                _size++;
        } // insertData    
    
        void sortData (string order) {
        // apply a sort on the the data in the datatable
                /* to complete */    
        } // sortData
    
        string listToCsv (string [] list) {
        // move a values list to a CSV line (string) using the separator csvchar to join the values
                int lng = list.length();
                string acc = "";
                for (int i=0; i<lng; i++) {
                        acc = acc + list[i];
                        if (i<(lng-1)) {acc = acc + _csvchar;}
                }
                return acc;   
        } // listToCsv
    
        string [] csvToList(string csv_line) {
        // move a CSV line (string) to a values list using the separator csvchar to disjoin the line values   
                string [] tmp = (string []) [];
                int lng = csv_line.length();
                string buffer = "";
                string char = "";
          
                // searching for the csv char, if the search failed, return the csvline
                if (csv_line.seek(_csvchar)==-1) {
                        tmp.pushBack(csv_line);
                        return tmp; 
                }

                for (int i=0; i<lng; i++) {
                        char = csv_line[i];
                        if (char==_csvchar) {
                                // put the buffer in tmp
                                tmp.pushBack(buffer);
                                // clear the buffer
                                buffer = "";
                        } else {
                                buffer = buffer + char;  
                        }
                }	 
                tmp.pushBack(buffer);
                return tmp;
         
        } // csvToList
    
        string [] matrixToCsv(string [][] matrix) {
        // move a string matrix to a string list using the separator csvchar to join the strings
                return (string []) []; 
                /* to complete */
        } // matrixToCsv
    
        string [][] CsvToMatrix(string [] csv_lines) {
        // move a string list to a string matrix using the separator csvchar to disjoin each line values 
                return (string [][]) [];
                /* to complete */
        } // CsvToMatrix
    
        void write (string filename) {
        // write all the csv data lines, contained in the datatable, on the file filename
                int lng = this->getSize();

                TextOutputFile file_out = new TextOutputFile(filename, false);
                for (int i=0; i<lng; i++) {
                        file_out->writeString(format(_datatable[i], "\n"));
                }
                file_out->close();
                        
        } // write
    
        void writeLines (string filename, int index1, int index2, bool append) {
        // Write the csv data lines contained in the datatable,
        // between the index index1 and index2, on the file filename.
        // If append is true, the content of the file will be completed at the end of the file,
        // otherwise (false) the file will be replaced by the new content.

                int lng = this->getSize();

                if (index1 > index2) {
                        warning("The second index should be greater than the first index\n");
	                return;
                }

                if (index1 < 0 || index1 > (lng-1)) {
                        warning("The first index is out of range\n");
                        return;
                }
	      
                if (index2 < 0 || index2 > (lng-1)) {
                        warning("The second index is out of range\n");
                        return;
                }

                TextOutputFile file_out = new TextOutputFile(filename, append);
                //if (append==true) file_out->writeString("\n");
                for (int i=index1; i<=index2; i++) { 
                        file_out->writeString(format(_datatable[i], "\n"));
                }
                file_out->close();
    
        } // writeLines
    
        string [] read (string filename) {
        // read the file filename line per line and return the content in a list of string
                string line = "";
                string [] csvlist = (string []) [];

                TextInputFile file_input = new TextInputFile(filename);
                if (file_input->fail()) return (string []) [];
                while (!file_input->eof()) {
                        line=file_input->readLine();
                        csvlist.pushBack(line);
                } // while
                file_input->close();

                return csvlist;
        } // read
   
        string [] readLines (string filename, int index, int numberofline) {
        // read the lines between index and index plus numberofline in the file filename
                return (string []) [];
                /* to complete */
        } // readLines

        void load (string filename) {
        // read the file filename line per line and load the content in a the datatable
                string line = "";
                _datatable.erase();  // clean the datatable
                _size=0;

                TextInputFile file_input = new TextInputFile(filename);
                if (file_input->fail()) return;
                while (!file_input->eof()) {
                        line=file_input->readLine();
                        _datatable.pushBack(line);
                        _size++;
                } // while
                file_input->close();

        } // load
 
} //Csvlib


endPackage // PLMCSV_IMP

