import paraview
import paraview.vtk as vtk
import paraview.simple as pvsimple

# initialize and read input parameters
paraview.options.batch = True
paraview.options.symmetric = True

def _refHolderMaker(obj):
    def _refHolder(obj2, string):
        tmp = obj
    return _refHolder


def DoCoProcessing(datadescription):
    "Callback to do co-processing for current timestep"
    timestep = datadescription.GetTimeStep()

    filename_0_pvti = CreateProducer( datadescription, "input" )
    ExtractSubset2 = pvsimple.ExtractSubset( guiName="ExtractSubset2", IncludeBoundary=0, VOI=[-10, -9, -10, -9, -10, -8], SampleRateK=1, SampleRateJ=1, SampleRateI=1 )
    writer = pvsimple.XMLPImageDataWriter()
    writer.FileName = "mytestextents.pvti"
    writer.UpdatePipeline()

    #ParallelImageDataWriter1 = CreateWriter( XMLPImageDataWriter, "filename2_%t.pvti", 1, cp_writers )

def CreateProducer(datadescription, gridname):
    "Creates a producer proxy for the grid"
    if not datadescription.GetInputDescriptionByName(gridname):
        raise RuntimeError, "Simulation input name '%s' does not exist" % gridname
    grid = datadescription.GetInputDescriptionByName(gridname).GetGrid()
    producer = pvsimple.PVTrivialProducer()
    producer.GetClientSideObject().SetOutput(grid)
    if grid.IsA("vtkImageData") == True or grid.IsA("vtkStructuredGrid") == True or grid.IsA("vtkRectilinearGrid") == True:
        extent = datadescription.GetInputDescriptionByName(gridname).GetWholeExtent()
        producer.WholeExtent= [ extent[0], extent[1], extent[2], extent[3], extent[4], extent[5] ]

    producer.UpdatePipeline()
    return producer


def CreateWriter(proxy_ctor, filename, freq, cp_writers):
    writer = proxy_ctor()
    writer.FileName = filename
    writer.add_attribute("cpFrequency", freq)
    writer.add_attribute("cpFileName", filename)
    cp_writers.append(writer)
    return writer

def coProcess(grid, time, step):
    import vtkCoProcessorPython # import libvtkCoProcessorPython for older PV versions
    datadescription = vtkCoProcessorPython.vtkCPDataDescription()
    datadescription.SetTimeData(time, step)
    datadescription.AddInput("input")
    datadescription.GetInputDescriptionByName("input").AllFieldsOn()
    datadescription.GetInputDescriptionByName("input").GenerateMeshOn()

    inputdescription = datadescription.GetInputDescriptionByName("input")
    if inputdescription.GetIfGridIsNecessary() == False:
        return

    inputdescription.SetGrid(grid)
    DoCoProcessing(datadescription)


time = 0
step = 0

# create the input to the coprocessing library.  normally
# this will come from the adaptor
wavelet = pvsimple.Wavelet()
wavelet.UpdatePipeline()
imageData = pvsimple.servermanager.Fetch(wavelet)

# note that we delete wavelet now since.  if not, it will
# get deleted automatically in the coprocessing script
pvsimple.Delete(wavelet)
wavelet = None

# "perform" coprocessing.  results are outputted only if
# the passed in script says we should at time/step
coProcess(imageData, time, step)
imageData = None
