import arcpy
from arcpy import env
from arcpy.sa import *
import os
import traceback
import sys
import math

class LicenseError(Exception):
    pass


class DataMissing(Exception):
    pass


def isArcMap():
	try:
		arcpy.mapping.MapDocument("CURRENT")
		return True
	except:
		return False
	

def runAnalysis(regenLayer,clipPoly,requiredHA,outName,imgExt):    
    try:
        regenImgDesc = arcpy.Describe(regenLayer)
        unitsName = regenImgDesc.spatialReference.linearUnitName
        cellWidth = Raster(regenRLyrName).meanCellWidth
        sqUnitsPerCell = cellWidth*cellWidth
        if "Meter" in unitsName:
            cnvUnits = 10000
        elif "Feet" in unitsName:
            cnvUnits =107639
        else:
            arcpy.AddError("Regeneration raster needs to be projected using units of meters or feet.")
            raise DataMissing
        cellsPerHa = cnvUnits/sqUnitsPerCell   
        
        arcpy.Clip_management(regenRLyrName,"#","clip"+imgExt,clipPoly,"NoData","ClippingGeometry")
        arcpy.BuildRasterAttributeTable_management("clip"+imgExt, "Overwrite")  
        #The negative one *-1* required due to output from database showing negative when there is a defeceit.
        cellsNeeded = math.ceil(requiredHA * cellsPerHa)
        #arcpy.AddMessage(str(cellsNeeded) + " cells needed")
        arcpy.Statistics_analysis("clip"+imgExt,"clip_Statistics"+tabExt,"Count SUM","#")
        statRows = arcpy.SearchCursor("clip_Statistics"+tabExt)
        
        totalCellsinClipRaster = -1
        for rowNeeded in statRows:
            totalCellsinClipRaster = rowNeeded.getValue("SUM_Count")
        #arcpy.AddMessage(str(totalCellsinClipRaster) + " total cells in raster")
        if totalCellsinClipRaster == -1:
            names = outName.split("_")
            arcpy.AddWarning("Parcel " + names[1] + " is completely covered by natural vegetation and does not require regeneration.  Check your regeneration hectare values for this parcel.")
            return        
        TargetNum = totalCellsinClipRaster - cellsNeeded

        if TargetNum > 0:
            currentNum = 0
            finalNum = 0
            rasterRows = arcpy.SearchCursor("clip"+imgExt)
            for rasRow in rasterRows:
                val = rasRow.getValue("Value")
                count = rasRow.getValue("Count")
                currentNum = currentNum+count
                if currentNum > TargetNum:
                    break
               
            finalNum = totalCellsinClipRaster - currentNum + count
            whereClause = "Value >= "+str(val)
            finalOutRaster = Con("clip"+imgExt,1,"",whereClause)
            if finalNum == 0:
                arcpy.AddMessage ("Total hectares identified for "+outName+ " = "+ str(totalCellsinClipRaster/cellsPerHa)+ " which is equal to all available converted lands within parcel.") 
            else:
                arcpy.AddMessage ("Total hectares identified for "+outName+ " = "+ str(finalNum/cellsPerHa))             
        else:
            finalOutRaster  = Con("clip"+imgExt,1)
            arcpy.AddMessage ("Total hectares identified for "+outName+ " = "+ str(totalCellsinClipRaster/cellsPerHa)+ " which is equal to all available converted lands within parcel.") 
                   
        finalOutRaster.save(outName)
 
            
        blnArcmap = isArcMap()
        if blnArcmap:
            #arcpy.MakeRasterLayer_management(arcpy.env.workspace+"\\"+outName,"rLayer")

            workspaceLoc = arcpy.env.workspace
            descWorkspace = arcpy.Describe(workspaceLoc)
            if descWorkspace.workspaceType == "FileSystem":
                type = "RASTER_WORKSPACE"
            else:
                type = "FILEGDB_WORKSPACE"
            try:
                mxd = arcpy.mapping.MapDocument('CURRENT')
                df = arcpy.mapping.ListDataFrames(mxd)[0]
                script_path=sys.argv[0]
                symb_dir = os.path.dirname(script_path) + '\\lyrfiles'
                lyr_symb = symb_dir + '\\ParcelRegenLoc.lyr'
                newlayer1 = arcpy.mapping.Layer(lyr_symb)
                newlayer1.replaceDataSource(workspaceLoc,type,outName)
                newlayer1.name = outName
                arcpy.mapping.AddLayer(df, newlayer1, "TOP")
                arcpy.RefreshActiveView()
                arcpy.RefreshTOC()
            except:
                nameLoc = arcpy.env.workspace+"\\"+outName
                arcpy.AddWarning("Could not create a layer in ArcMap for " +nameLoc)
                arcpy.AddWarning("You will need to add these data manually.") 
                #pass
            #arcpy.ApplySymbologyFromLayer_management (newlayer1, lyr_symb)


    except:
        tb = sys.exc_info()[2]
        tbinfo = traceback.format_tb(tb)[0]
        pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)
        arcpy.AddError(pymsg)

        

try:
    imgExt =""
    tabExt=""
    shpExt=""
    toDelete = []
    
    if arcpy.CheckExtension("Spatial") == "Available":
        arcpy.CheckOutExtension("Spatial")
    else:
        raise LicenseError

    parcelLyrName = arcpy.GetParameterAsText(0)
    uIDfld = arcpy.GetParameterAsText(1)
    haFieldName = arcpy.GetParameterAsText(2)
    regenRLyrName = arcpy.GetParameterAsText(3)
    outWorkspace = arcpy.GetParameterAsText(4)

    arcpy.env.overwriteOutput = 1
    wsDesc = arcpy.Describe(outWorkspace)   

    if wsDesc.workspaceType == "FileSystem":
        imgExt =".img"
        tabExt = ".dbf"
        shpExt=".shp"

        
#Getting cargio workspace --------------

 
    
    arcpy.env.outputCoordinateSystem = regenRLyrName
    arcpy.env.workspace = outWorkspace
    arcpy.env.scratchWorkspace = outWorkspace
   
    
    arcpy.CopyFeatures_management(parcelLyrName,"regenParcelsAnalyzed"+shpExt)
    toDelete.append("regenParcelsAnalyzed"+shpExt)
    arcpy.MakeFeatureLayer_management("regenParcelsAnalyzed"+shpExt,"Parcels4Analysis")
    toDelete.append("Parcels4Analysis")
    
    totalCount = int(arcpy.GetCount_management("Parcels4analysis").getOutput(0))
    desc4Analysis = arcpy.Describe("Parcels4analysis")
    shpFieldName = desc4Analysis.ShapeFieldName
    calculatingParcel = 1
    parcelsWORecords = 0   
    
    i=0
    
    
    for row in arcpy.da.SearchCursor("Parcels4analysis",("SHAPE@",uIDfld,haFieldName)):
        poly = row[0]
        parcelID = row[1]
        hects = row[2]
        if parcelID is None:
            arcpy.AddWarning("Row "+str(i)+ " is missing an id value.  It will be skipped")
            parcelsWORecords = parcelsWORecords+1
            continue
            
        if hects < 0.1:
            arcpy.AddMessage ("Parcel "+ str(parcelID) + " has 0 hectares designated for regeneration and will be skipped.")
        else:
           name4output = "Parcel_"+str(parcelID) +"_Regen_Prior"+ imgExt
           runAnalysis(regenRLyrName,poly,hects,name4output,imgExt)

    
except LicenseError:
    arcpy.AddError ("Spatial Analyst license is unavailable") 	


except DataMissing:
    arcpy.AddError ("Data Input Error.")


except:
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)
    arcpy.AddError(pymsg)
    
finally:
    arcpy.AddMessage("Removing Temporary Files.")
    if arcpy.Exists("Parcels4Analysis"):
        arcpy.Delete_management("Parcels4Analysis")
    if arcpy.Exists("clip"+imgExt):
        arcpy.Delete_management("clip"+imgExt)
    if arcpy.Exists("clip_Statistics"+tabExt):
        arcpy.Delete_management("clip_Statistics"+tabExt)
    if arcpy.Exists("regenParcelsAnalyzed"+shpExt):
        arcpy.Delete_management("regenParcelsAnalyzed"+shpExt)
    if arcpy.Exists("clipOut"+shpExt):
        arcpy.Delete_management("clipOut"+shpExt)
    arcpy.AddMessage("Analysis Finished!")
    #arcpy.AddMessage("Data found in selected output workspace:  "+outWorkspace)
    if parcelsWORecords > 0:
        arcpy.AddWarning(str(parcelsWORecords)+" of the selected parcels did not have a property code necessary for the analysis.")