#include <stdio.h>
#include "GR_misc.h"
#include "GR_events.h"
#include "GR_Face.h"
#include "GR_Cell.h"
#include "GR_BFace.h"
#include "GR_Vertex.h"
#include "GR_Mesh2D.h"
void vWriteFile_Mesh2D(Mesh2D& OutMesh,
                        const char strBaseFileName[],
                        const char strExtraFileSuffix[])
{
  SUMAA_LOG_EVENT_BEGIN(OUTPUT);
  //  assert(OutMesh.qSimplicial());
  int iVertOffset = 0, iFaceOffset = 0;
  int iCellOffset = 0, iBFaceOffset = 1;
  FILE *pFOutFile = fopen("/dev/zero", "r");
  char strFileName[1024];
  OutMesh.vPurge();
  sprintf(strFileName, "%s.mesh%s", strBaseFileName, strExtraFileSuffix);

  /*newfile mesh*/
  printf("Opening output file %s\n", strFileName);
  if (pFOutFile) fclose(pFOutFile);
  pFOutFile = fopen(strFileName, "w");
  if (NULL == pFOutFile)
    vFatalError("Couldn't open output file for writing",
                "2d mesh output");

  /*ncells nfaces nbfaces nverts*/
  fprintf(pFOutFile, "%d %d %d %d\n", OutMesh.iNumCells(), OutMesh.iNumFaces(), OutMesh.iNumBdryFaces(), OutMesh.iNumVerts());

  for (int iV = 0; iV < OutMesh.iNumVerts(); iV++) 
    /*verts: coords*/
    fprintf(pFOutFile, "%.14g %.14g\n", OutMesh.pVVert(iV)->dX(), OutMesh.pVVert(iV)->dY());


  for (int iF = 0; iF < OutMesh.iNumFaces(); iF++) {
    Face* pF = OutMesh.pFFace(iF);
    int iCA, iCB;
    Cell *pC = pF->pCCellLeft();
    switch (pC->eType()) {
    case Cell::eBdryEdge:
    case Cell::eTriBFace:
    case Cell::eQuadBFace:
    case Cell::eIntBdryEdge:
    case Cell::eIntTriBFace:
    case Cell::eIntQuadBFace:
      iCA = - (dynamic_cast<BFace*>(pC))->iBdryCond();
      break;
//    case Cell::eIntBdryEdge:
//    case Cell::eIntTriBFace:
//    case Cell::eIntQuadBFace:
//      {
//        Face *pFOther = pC->pFFace(0);
//        if (pF == pFOther) pFOther = pC->pFFace(1);
//        Cell *pCOther = pFOther->pCCellOpposite(pC);
//        iCA = OutMesh.iCellIndex(pCOther)+iCellOffset;
//      }
//      break;
    default:
      iCA = OutMesh.iCellIndex(pC)+iCellOffset;
      break;
    }

    pC = pF->pCCellRight();
    switch (pC->eType()) {
    case Cell::eBdryEdge:
    case Cell::eTriBFace:
    case Cell::eQuadBFace:
    case Cell::eIntBdryEdge:
    case Cell::eIntTriBFace:
    case Cell::eIntQuadBFace:
      iCB = - (dynamic_cast<BFace*>(pC))->iBdryCond();
      break;
//    case Cell::eIntBdryEdge:
//    case Cell::eIntTriBFace:
//    case Cell::eIntQuadBFace:
//      {
//        Face *pFOther = pC->pFFace(0);
//        if (pF == pFOther) pFOther = pC->pFFace(1);
//        Cell *pCOther = pFOther->pCCellOpposite(pC);
//        iCB = OutMesh.iCellIndex(pCOther)+iCellOffset;
//      }
//      break;
    default:
      iCB = OutMesh.iCellIndex(pC)+iCellOffset;
      break;
    }
    /*faces: cells verts*/
    fprintf(pFOutFile, "%d %d %d %d\n", iCA, iCB, OutMesh.iVertIndex(pF->pVVert(0))+iVertOffset, OutMesh.iVertIndex(pF->pVVert(1))+iVertOffset);
  }


  for (int iBF = 0; iBF < OutMesh.iNumBdryFaces(); iBF++) {
    BFace* pBF = OutMesh.pBFBFace(iBF);
    /*bdryfaces: face bc verts*/
    fprintf(pFOutFile, "%d %d %d %d\n", OutMesh.iFaceIndex(pBF->pFFace(0))+iFaceOffset, pBF->iBdryCond(), OutMesh.iVertIndex(pBF->pVVert(0))+iVertOffset, OutMesh.iVertIndex(pBF->pVVert(1))+iVertOffset);
  }


  for (int iC = 0; iC < OutMesh.iNumCells(); iC++) {
    Cell* pC = OutMesh.pCCell(iC);
    /*cells: region*/
    fprintf(pFOutFile, "%d\n", pC->iRegion());
  }

  /* Make sure compilers won't complain that these variables */
  /* aren't used. */
  iVertOffset++;
  iFaceOffset++;
  iBFaceOffset++;
  iCellOffset++;
  fclose(pFOutFile);
  SUMAA_LOG_EVENT_END(OUTPUT);
}
