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

class OneParcelOnlyError (Exception):
    pass

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


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

    parcelLyrName = arcpy.GetParameterAsText(0)
    parcelIdField = arcpy.GetParameterAsText(1)
    regenRLyrName = arcpy.GetParameterAsText(2)
    parcelRanked = arcpy.GetParameterAsText(3)
    groupList = arcpy.GetParameterAsText(4)


    
    regenParcelRankDesc = arcpy.Describe(parcelRanked)
    outWorkspace = regenParcelRankDesc.path
    

    arcpy.env.overwriteOutput = 1

    wsDesc = arcpy.Describe(outWorkspace)   

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


    parcelDesc = arcpy.Describe(parcelLyrName)
    parcelPath = parcelDesc.path   
    descParcelPath = arcpy.Describe(parcelPath)
    parcelWorkspace = descParcelPath.path
    catPath = descParcelPath.catalogPath



    arcpy.env.outputCoordinateSystem = regenRLyrName
    arcpy.env.workspace = outWorkspace
    arcpy.env.scratchWorkspace = outWorkspace
    arcpy.env.overwriteOutput = True
    
    pDesc = arcpy.Describe(parcelLyrName)
    if pDesc != "FeatureLayer":
        paLayer = "xxlgParcels"
        arcpy.MakeFeatureLayer_management(parcelLyrName,paLayer)
        toDelete.append("xxlgParcels")
    else:
        paLayer = parcelLyrName
    
    
    arcpy.RasterToPoint_conversion(parcelRanked,"rankedPts"+shpExt,"VALUE")
    toDelete.append("rankedPts"+shpExt)
    arcpy.MakeFeatureLayer_management("rankedPts"+shpExt,"RankedPtsLyr")
    toDelete.append("RankedPtsLyr")
    toDelete.append("rankedPts"+shpExt)
    arcpy.SelectLayerByLocation_management(paLayer,"intersect","RankedPtsLyr")
    noParcelsSelected = int(arcpy.GetCount_management(paLayer).getOutput(0))
    
    parcel_rows = arcpy.da.SearchCursor(paLayer,("SHAPE@",parcelIdField))
    if noParcelsSelected == 1:
        parcelrow = parcel_rows.next()
        clipPoly = parcelrow[0]
        locID = parcelrow[1]
    else:
        val = 0
        for parcelrow in parcel_rows:
            shp = parcelrow[0]
            arcpy.SelectLayerByLocation_management("RankedPtsLyr","intersect",shp)
            ptsSel = int(arcpy.GetCount_management("RankedPtsLyr").getOutput(0))
            if ptsSel > val:
                clipPoly = parcelrow[0]
                locID = parcelrow[1]
                val = ptsSel
        


    arcpy.Clip_management(regenRLyrName,"#","clipRegen"+imgExt,clipPoly,"NoData","ClippingGeometry")
    toDelete.append("clipRegen"+imgExt)
    arcpy.Statistics_analysis(parcelRanked,"totalcellsNeeded"+tabExt,"Count SUM","#")
    toDelete.append("totalcellsNeeded"+tabExt)
    statRows = arcpy.SearchCursor("totalcellsNeeded"+tabExt)
    statRow = statRows.next()
    TotalCellsNeeded = statRow.getValue("SUM_COUNT")
    conString =""
    groupVals =""
    numList = groupList.split(";")
    for num in numList:
        groupVals =groupVals + str(num)
        conString = conString + "Value = "+str(num)+ " or "
        
    whereClause = conString.rstrip(" or ")
    #arcpy.AddMessage(whereClause)
    conOut = Con(parcelRanked,1,"",whereClause)
    arcpy.Statistics_analysis(conOut,"totalcellsRanked"+tabExt,"Count SUM","#")
    toDelete.append("totalcellsRanked"+tabExt)
    statRows = arcpy.SearchCursor("totalcellsRanked"+tabExt)
    statRow = statRows.next()
    CellsRanked = statRow.getValue("SUM_COUNT")
    CellsNeeded = TotalCellsNeeded - CellsRanked
    arcpy.env.mask = "clipRegen"+imgExt
    EucDist = EucDistance(conOut)
    FinalInt = Int(Plus("clipRegen"+imgExt,(Times(Divide(1,SquareRoot(EucDist)),1000))))#FinalInt = Int(Divide(Times(1000,"clipRegen"+imgExt),EucDist))

    

    
    arcpy.Statistics_analysis(FinalInt,"finalInt"+tabExt,"Count SUM","#")
    toDelete.append("finalInt"+tabExt)
    statRows = arcpy.SearchCursor("finalInt"+tabExt)
    statRow = statRows.next()
    AllCells = statRow.getValue("SUM_COUNT")
    TargetNum = AllCells - CellsNeeded
    rasterRows = arcpy.SearchCursor(FinalInt)
    currentNum = 0
    for rasRow in rasterRows:
        val = rasRow.getValue("Value")
        count = rasRow.getValue("Count")
        currentNum = currentNum+count
        if currentNum > TargetNum:
            break
    whereClause = "Value >= "+str(val)
    addCon = Con(FinalInt,1,"",whereClause)
    
    areaOut = CellStatistics([conOut,addCon],"MAXIMUM","DATA")
    ZStatGrid = ZonalStatistics(areaOut,"Value","clipRegen"+imgExt,"SUM","DATA")
    
    FinalOut = Int(ZStatGrid)
    outName = "Parcel_"+str(locID)+"_Regen_GRP"+groupVals
    FinalOut.save(outName+imgExt)
    rasterRows = arcpy.SearchCursor(FinalOut)
    rasRow = rasterRows.next()
    regenValue = rasRow.getValue("Value")
    #arcpy.BuildRasterAttributeTable_management("TestingOut"+imgExt, "Overwrite")
    arcpy.AddMessage("Overal allocation score for this raster is "+str(regenValue)+".")
    arcpy.AddMessage("Cell values for raster all equal to this overal score.")
    blnArcmap = isArcMap()
    if blnArcmap:
         workspaceLoc = arcpy.env.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 + '\\ParcelRegenZoneGrouping.lyr' 
             newlayer1 = arcpy.mapping.Layer(lyr_symb)
             newlayer1.name = outName             
             newlayer1.replaceDataSource(workspaceLoc,wtype,outName+imgExt)
             arcpy.mapping.AddLayer(df, newlayer1, "TOP")
             arcpy.RefreshActiveView()
             arcpy.RefreshTOC()
         except:
             nameLoc = arcpy.env.workspace+"\\"+outName+imgExt
             arcpy.AddWarning("Could not create a layer in ArcMap for " +nameLoc)
             arcpy.AddWarning("You will need to add these data manually.") 

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


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

except OneParcelOnlyError:
    arcpy.AddError("Need to have only one feature selected.")

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.")     
    for d in toDelete:
        try:
           arcpy.Delete_management(d)
        except:
           arcpy.AddMessage("Could not delete "+d)
           continue
    i = 0
    while (i<10):
       if arcpy.Exists("GPL"+str(i)):
        try:
           arcpy.Delete_management("GPL"+str(i))
        except:
            continue
       i =  i + 1
