/* ============================= C MeatAxe ==================================
   File:        $Id: genmod.c,v 1.2 2007-11-08 22:06:52 mringe Exp $
   Comment:     This program calculates a basis for any submodule listet in
		the .out file.
   --------------------------------------------------------------------------
   (C) Copyright 1997 Michael Ringe, Lehrstuhl D fuer Mathematik,
   RWTH Aachen, Germany  <mringe@math.rwth-aachen.de>
   This program is free software; see the file COPYING for details.
   ========================================================================== */

#include "meataxe.h"
#include <string.h>
#include <stdlib.h>



/* ------------------------------------------------------------------
   Global data
   ------------------------------------------------------------------ */

MTX_DEFINE_FILE_INFO

MatRep_t *Rep;			/* Generators for the algebra */
Matrix_t *mountains;		/* Genrators for all mountains */
int nmount;			/* Number of mountains */
int modnum;
BitString_t *bs;		/* Bit string read from .sub file */
int opt_m = 0;			/* Option -m used */
static Lat_Info LI;		/* Data from .cfinfo file */
static const char *ModuleName = NULL;

static MtxApplicationInfo_t AppInfo = {
"genmod", "Make submodule",
"SYNTAX"
"    genmod [-QVm] <Name> <Number>\n"
"\n"
"ARGUMENTS\n"
"    <Name> .................. Module name\n"
"    <Number> ................ Submodule number\n"
"\n"
"OPTIONS\n"
MTX_COMMON_OPTIONS_DESCRIPTION
"    -m ...................... Make mountain (works after mkinc)\n"
"\n"
"FILES\n"
"    <Name>.sub .............. I  Submodule information (generated by mksub)\n"
"    <Name>.v ................ I  Mountains\n"
"    <Name>.s<Number> ........ O  The result (without -m)\n"
"    <Name>.m<Number> .........O  The result (with -m)\n"
};

static MtxApplication_t *App = NULL;






/* -----------------------------------------------------------------
   init() - Read generators and mountains
   ----------------------------------------------------------------- */

static int Init(int argc, const char **argv)

{
    char fn[200];
    FILE *f;
    int i;

    App = AppAlloc(&AppInfo,argc,argv);
    opt_m = AppGetOption(App,"-m --mountain");
    if (AppGetArguments(App,2,2) < 0)
	return -1;
    ModuleName = App->ArgV[0];
    modnum = atoi(App->ArgV[1]);
    if (Lat_ReadInfo(&LI,ModuleName) != 0)
    {
	MTX_ERROR1("Error reading %s.cfinfo",ModuleName);
	return -1;
    }

    /* Read the generators and mountains.
       ---------------------------------- */
    if ((Rep = MrLoad(ModuleName,LI.NGen)) == NULL)
	return -1;
    mountains = MatLoad(strcat(strcpy(fn,LI.BaseName),".v"));
    nmount = mountains->Nor;
    MESSAGE(1,("%d mountains\n",nmount));


    /* Read the bit string from xxx.sub or set up the bit string
       to contain only the requested mountain (-m)
      ------------------------ --------------------------------- */
    if (opt_m)
    {
	bs = BsAlloc(nmount);
	BsSet(bs,modnum);
    }
    else
    {
    	f = SysFopen(strcat(strcpy(fn,LI.BaseName),".sub"),FM_READ);
    	if (f == NULL)
	    MTX_ERROR("CANNOT OPEN .sub FILE");
	bs = BsAlloc(nmount);
    	SysFseek(f,modnum * (12 + (bs->Size + 7) / 8));	/* HACK: !!! */
	BsFree(bs);
    	bs = BsRead(f);
    	if (MSG1)
    	{
	    printf("Mountains: ");
	    for (i = 0; i < nmount; ++i)
	    	if (BsTest(bs,i)) printf("%d ",i);
	    printf("\n");
    	}
	fclose(f);
    }

    return 0;
}



/* -----------------------------------------------------------------
   sp()
   ----------------------------------------------------------------- */

static void sp()

{
    int i;
    Matrix_t *m, *subsp;
    PTR p;
    char fn[200];

    m = MatAlloc(FfOrder,nmount,Rep->Gen[0]->Noc);
    p = m->Data;
    for (i = 0; i < nmount; ++i)
    {
	if (BsTest(bs,i))
	{
	    PTR q = FfGetPtr(mountains->Data,i);
	    FfCopyRow(p,q);
	    FfStepPtr(&p);
	}
    }
    MatEchelonize(m);
    MESSAGE(0,("Seed space has dimension %d\n",m->Nor));
    subsp = SpinUp(m,Rep,SF_EACH|SF_COMBINE,NULL,NULL);
    MESSAGE(0,("Submodule has dimension %d\n",subsp->Nor));
    sprintf(fn,"%s.%c%d",LI.BaseName,opt_m ? 'm' : 's',modnum);
    MatSave(subsp,fn);
    MESSAGE(0,("Module written to `%s'\n",fn));
}


/* -----------------------------------------------------------------
   main()
   ----------------------------------------------------------------- */

int main(int argc, const char *argv[])

{
    if (Init(argc,argv) != 0)
    {
	MTX_ERROR("Initialization failed");
	return -1;
    }


    sp();
    AppFree(App);
    return 0;
}



/**
@page prog_genmod genmod - Make Submodule

@section genmod-syntax Command Line
<pre>
genmod @em Options [-m] @em Name @em Number
</pre>

@par @em Options
  Standard options, see @ref prog_stdopts
@par -m
  Make mountain (works after @ref prog_pwkond "pwkond").
@par @em Name
  Module name.
@par @em Number
  Submodule number.

@section genmod-inp Input Files
@par @em Name.sub
  Submodule information.
@par @em Name.v
  Mountains.

@section genmod-out Output Files
@par Name.sNumber, Name.mNumber
  The result (see decription).

@section genmod-desc Description
This program makes a submodule, i.e., it takes the mountains
contained in that submodule and spins them up. The result
is written to <em>Name</em>.s<em>Number</em>. The program assumes that
the submodule structure has been calculated with @ref prog_mksub "mksub".

If the -m option is used, @em Number is treated as the
number of a mountain. This mountain is generated and written
to  <em>Name</em>.m<em>Number</em>.

**/

