//---------------------------------------------------------
bool CCRU_Table_Import::On_Execute(void)
{
	//-----------------------------------------------------
	CSG_File	File;

	if( !File.Open(Parameters("FILE")->asString(), SG_FILE_R, false) )
	{
		Error_Fmt("%s [%s]", _TL("could not open file"), Parameters("FILE")->asString());

		return( false );
	}

	//-----------------------------------------------------
	CSG_String	sLine;

	if( !File.Read_Line(sLine) )
	{
		Error_Fmt("%s [%s]", _TL("failed to read header"), Parameters("FILE")->asString());

		return( false );
	}

	//-----------------------------------------------------
	int		nx, ny, nMonths;
	double	Cellsize, xMin, yMin, xMax, yMax;

	if( !File.Scan(Cellsize)
	||  !File.Scan(xMin    ) || !File.Scan(yMin    )
	||  !File.Scan(xMax    ) || !File.Scan(yMax    )
	||  !File.Scan(nx      ) || !File.Scan(ny      )
	||  !File.Scan(nMonths ) )
	{
		Error_Fmt("%s [%s]", _TL("failed to read header"), Parameters("FILE")->asString());

		return( false );
	}

	//-----------------------------------------------------
	CSG_Grid_System	System(Cellsize, xMin, yMin, nx, ny);

	if( !System.is_Valid() || System.Get_XMax() != xMax || System.Get_YMax() != yMax )
	{
		Error_Fmt("%s [%s]", _TL("failed to read header"), Parameters("FILE")->asString());

		return( false );
	}

	//-----------------------------------------------------
	bool	bShift	= Parameters("SHIFT")->asBool();

	if( bShift )
	{
		System.Assign(Cellsize, xMin - 180.0, yMin, nx, ny);
	}

	//-----------------------------------------------------
	CSG_String	Name	= SG_File_Get_Name(Parameters("FILE")->asString(), false);

	Parameters("GRIDS")->asGridList()->Del_Items();

	for(int iMonth=0; iMonth<nMonths && !File.is_EOF() && Process_Get_Okay(); iMonth++)
	{
		Process_Set_Text("%s %d", _TL("Band"), 1 + iMonth);

		CSG_Grid	*pGrid	= SG_Create_Grid(System, SG_DATATYPE_Short);

		pGrid->Fmt_Name("%s_%02d", Name.c_str(), 1 + iMonth);
		pGrid->Set_NoData_Value(-9999);
		pGrid->Get_Projection().Set_GCS_WGS84();

		Parameters("GRIDS")->asGridList()->Add_Item(pGrid);

		//-------------------------------------------------
		for(int y=0; y<ny && !File.is_EOF() && Set_Progress(y, ny); y++)
		{
			if( File.Read_Line(sLine) && sLine.Length() >= 5. * nx )
			{
				for(int x=0, xx=bShift?nx/2:x, yy=ny-1-y; x<nx; x++, xx++)
				{
					double	z;

					CSG_String	s	= sLine.Mid(x * 5, 5);

					if( s.asDouble(z) )
					{
						pGrid->Set_Value(xx % nx, yy, z);
					}
					else
					{
						pGrid->Set_NoData(xx % nx, yy);
					}
				}
			}
		}
	}

	//-----------------------------------------------------
	return( true );
}
//---------------------------------------------------------
bool CTable_Text_Import_Fixed_Cols::On_Execute(void)
{
    bool			bHeader;
    int				i, nChars, iField, nFields, *iFirst, *iLength;
    CSG_String		sLine;
    CSG_File		Stream;
    CSG_Table		*pTable;

    //-----------------------------------------------------
    pTable	= Parameters("TABLE")		->asTable();
    bHeader	= Parameters("HEADLINE")	->asBool();

    //-----------------------------------------------------
    if( !Stream.Open(Parameters("FILENAME")->asString(), SG_FILE_R, true) )
    {
        Message_Add(_TL("file could not be opened"));

        return( false );
    }

    if( !Stream.Read_Line(sLine) || (nChars = (int)sLine.Length()) <= 0 )
    {
        Message_Add(_TL("empty or corrupted file"));

        return( false );
    }

    //-----------------------------------------------------
    pTable->Destroy();
    pTable->Set_Name(SG_File_Get_Name(Parameters("FILENAME")->asString(), false));

    switch( Parameters("FIELDDEF")->asInt() )
    {
    //-----------------------------------------------------
    case 0:
    {
        CSG_Parameters	*pBreaks	= Get_Parameters("BREAKS");

        pBreaks->Del_Parameters();

        for(i=0; i<nChars; i++)
        {
            pBreaks->Add_Value(NULL,
                               CSG_String::Format(SG_T("%03d"), i),
                               CSG_String::Format(SG_T("%03d %c"), i + 1, sLine[i]),
                               _TL(""), PARAMETER_TYPE_Bool, false
                              );
        }

        if( !Dlg_Parameters("BREAKS") )
        {
            return( false );
        }

        //-------------------------------------------------
        for(i=0, nFields=1; i<pBreaks->Get_Count(); i++)
        {
            if( pBreaks->Get_Parameter(i)->asBool() )
            {
                nFields++;
            }
        }

        //-------------------------------------------------
        iFirst		= new int[nFields];
        iLength		= new int[nFields];

        iFirst[0]	= 0;

        for(i=0, iField=1; i<pBreaks->Get_Count() && iField<nFields; i++)
        {
            if( pBreaks->Get_Parameter(i)->asBool() )
            {
                iFirst[iField++]	= i + 1;
            }
        }

        //-------------------------------------------------
        for(iField=0; iField<nFields; iField++)
        {
            iLength[iField]	= (iField < nFields - 1 ? iFirst[iField + 1] : (int)sLine.Length()) - iFirst[iField];

            pTable->Add_Field(bHeader ? sLine.Mid(iFirst[iField], iLength[iField]) : CSG_String::Format(SG_T("FIELD%03d"), iField + 1), SG_DATATYPE_String);
        }
    }
    break;

    //-----------------------------------------------------
    case 1:
    {
        CSG_Parameters	*pFields	= Get_Parameters("FIELDS");

        pFields->Del_Parameters();

        nFields	= Parameters("NFIELDS")->asInt();

        for(iField=0; iField<nFields; iField++)
        {
            CSG_String		s		= CSG_String::Format(SG_T("%03d"), iField);
            CSG_Parameter	*pNode	= pFields->Add_Node(NULL, SG_T("NODE") + s, _TL("Field") + s, _TL(""));
            pFields->Add_Value	(pNode, SG_T("LENGTH") + s, _TL("Length"), _TL(""), PARAMETER_TYPE_Int, 1, 1, true);
            //	pFields->Add_Value	(pNode, SG_T("IMPORT") + s, _TL("Import"), _TL(""), PARAMETER_TYPE_Bool, true);
            pFields->Add_Choice	(pNode, SG_T("TYPE")   + s, _TL("Type")  , _TL(""), CSG_String::Format(SG_T("%s|%s|%s|%s|%s|"),
                                 _TL("text"),
                                 _TL("2 byte integer"),
                                 _TL("4 byte integer"),
                                 _TL("4 byte float"),
                                 _TL("8 byte float"))
                                );
        }

        if( !Dlg_Parameters("FIELDS") )
        {
            return( false );
        }

        //-------------------------------------------------
        iFirst		= new int[nFields];
        iLength		= new int[nFields];

        iFirst[0]	= 0;

        for(iField=0, i=0; iField<nFields && i<nChars; iField++)
        {
            CSG_String		s		= CSG_String::Format(SG_T("%03d"), iField);

            iFirst [iField]	= i;
            iLength[iField]	= pFields->Get_Parameter(SG_T("LENGTH") + s)->asInt();

            i	+= iLength[iField];

            CSG_String		Name	= bHeader ? sLine.Mid(iFirst[iField], iLength[iField]) : CSG_String::Format(SG_T("FIELD%03d"), iField + 1);

            switch( pFields->Get_Parameter(SG_T("TYPE") + s)->asInt() )
            {
            default:
            case 0:
                pTable->Add_Field(Name, SG_DATATYPE_String);
                break;
            case 1:
                pTable->Add_Field(Name, SG_DATATYPE_Short);
                break;
            case 2:
                pTable->Add_Field(Name, SG_DATATYPE_Int);
                break;
            case 3:
                pTable->Add_Field(Name, SG_DATATYPE_Float);
                break;
            case 4:
                pTable->Add_Field(Name, SG_DATATYPE_Double);
                break;
            }
        }
    }
    break;

    //-----------------------------------------------------
    case 2:
    {
        CSG_Table	*pList	= Parameters("LIST")->asTable();

        nFields	= pList->Get_Count();

        //-------------------------------------------------
        iFirst		= new int[nFields];
        iLength		= new int[nFields];

        iFirst[0]	= 0;

        for(iField=0, i=0; iField<nFields && i<nChars; iField++)
        {
            iFirst [iField]	= i;
            iLength[iField]	= pList->Get_Record(iField)->asInt(1);

            i	+= iLength[iField];

            CSG_String		Name	= bHeader ? sLine.Mid(iFirst[iField], iLength[iField]) : CSG_String(pList->Get_Record(iField)->asString(0));

            switch( pList->Get_Record(iField)->asInt(2) )
            {
            case 0:
                pTable->Add_Field(Name, SG_DATATYPE_String);
                break;
            case 1:
                pTable->Add_Field(Name, SG_DATATYPE_Short);
                break;
            case 2:
                pTable->Add_Field(Name, SG_DATATYPE_Int);
                break;
            case 3:
                pTable->Add_Field(Name, SG_DATATYPE_Float);
                break;
            default:
            case 4:
                pTable->Add_Field(Name, SG_DATATYPE_Double);
                break;
            }
        }
    }
    break;
    }

    //-----------------------------------------------------
    if( bHeader )
    {
        Stream.Read_Line(sLine);
    }

    //-----------------------------------------------------
    int		fLength	= Stream.Length();

    do
    {
        if( sLine.Length() == nChars )
        {
            CSG_Table_Record	*pRecord	= pTable->Add_Record();

            for(iField=0; iField<nFields; iField++)
            {
                pRecord->Set_Value(iField, sLine.Mid(iFirst[iField], iLength[iField]));
            }
        }
    }
    while( Stream.Read_Line(sLine) && Set_Progress(Stream.Tell(), fLength) );

    //-----------------------------------------------------
    delete[](iFirst);
    delete[](iLength);

    //-----------------------------------------------------
    return( true );
}