import arcpy
import time
import os
import sys



inFeatureClass = arcpy.GetParameterAsText(0)
outFeatureClass = arcpy.GetParameterAsText(4)
scale = arcpy.GetParameter(1)
sheet_width = arcpy.GetParameter(2)
sheet_high = arcpy.GetParameter(3)
outputFeatureClassPath = os.path.dirname(outFeatureClass)
toolSharePath = os.path.dirname(outputFeatureClassPath)
arcpy.AddMessage("ToolShare folder: " + toolSharePath)
arcpy.AddMessage("Output folder: " + outputFeatureClassPath)

arcpy.env.workspace = outputFeatureClassPath
arcpy.env.overwriteOutput = True   #overwrite temporary files

#############################################
##separating detouch groups of polygons of basin
##making a grid
##Michal Becicka, CTU in Prague, 2013
#############################################


#creating list of IDs
rows = arcpy.SearchCursor(inFeatureClass)

IDs=[]

for row in rows:
    IDs.append(row.OBJECTID)

#make string
sheet_width_str = str(sheet_width)+' centimeters'
sheet_high_str = str(sheet_high)+' centimeters'
scale_str = str(scale)

#variable for name of output
i = 0
page_number = 0

#list for merging grids layers
merge_list = []

#make feature layer
arcpy.MakeFeatureLayer_management(inFeatureClass, "povodi_class")

#list for count of map sheets
count_of_sheets=[]

#add field if doesn't exist
fieldList = arcpy.ListFields(inFeatureClass, 'section') 
fieldCount = len(fieldList)

if (fieldCount != 1):
    arcpy.AddField_management(inFeatureClass, 'section', 'SHORT')

#add field if doesn't exist
fieldList = arcpy.ListFields(inFeatureClass, 'MapSheets') 
fieldCount = len(fieldList)

if (fieldCount != 1):
    arcpy.AddField_management(inFeatureClass, 'MapSheets', 'TEXT')

#add field if doesn't exist
fieldList = arcpy.ListFields(inFeatureClass, 'hard_ID') 
fieldCount = len(fieldList)

if (fieldCount != 1):
    arcpy.AddField_management(inFeatureClass, 'hard_ID', 'SHORT')

rows = arcpy.UpdateCursor(inFeatureClass)

for row in rows:
    row.hard_ID = row.OBJECTID
    rows.updateRow(row)
del rows, row


##main part
while len(IDs) > 0 :

    i = i + 1
    basin_count=len(IDs)
    arcpy.AddMessage('_____________________________________________________________________\n')
    arcpy.AddMessage('count of basin polygon to process: ' + str(basin_count))
    arcpy.AddMessage('_____________________________________________________________________\n')
    arcpy.AddMessage('RUN ' + str(i))

    #selection of first nonprocessed polygon of basin
    first_ID = str(IDs[0])
    fieldName = "OBJECTID"
    Query = "\"" + fieldName  + "\" = " + first_ID
    arcpy.SelectLayerByAttribute_management('povodi_class', 'NEW_SELECTION', Query)
    matchcount1 = int(arcpy.GetCount_management('povodi_class').getOutput(0))

    #first selection of boundary touches polygons
    arcpy.SelectLayerByLocation_management('povodi_class', 'BOUNDARY_TOUCHES', 'povodi_class')
    matchcount2 = int(arcpy.GetCount_management('povodi_class').getOutput(0))

    #next selections of boundary touches polygons
    while matchcount1 < matchcount2:
        matchcount1 = matchcount2
        arcpy.SelectLayerByLocation_management('povodi_class', 'BOUNDARY_TOUCHES', 'povodi_class')
        matchcount2 = int(arcpy.GetCount_management('povodi_class').getOutput(0))

    rows_sel_u = arcpy.UpdateCursor('povodi_class')
    for row_sel_u in rows_sel_u:
        row_sel_u.section = i
        rows_sel_u.updateRow(row_sel_u)

    del rows_sel_u, row_sel_u
        
    #printing a log and saving a result
    rows_sel = arcpy.SearchCursor('povodi_class')
    IDs_sel=[]
    arcpy.AddMessage('count of basins in ' + str(i) + '. section: ' +str(matchcount2))
    arcpy.AddMessage('Their ID: ')
    
    for row_sel in rows_sel:
        IDs.remove(row_sel.OBJECTID)
        arcpy.AddMessage('          ID: ' + str(row_sel.OBJECTID))
        IDs_sel.append(row_sel.OBJECTID)

    del rows_sel, row_sel
    
    basin_count2=len(IDs)

    #prepare names
    output_name = 'section_N_' + str(i)
    grid_name = 'grid_N_' + str(i)
    
    if i < 10:
        output_name = 'section_N_0' + str(i)
        grid_name = 'grid_N_0' + str(i)

    #make a layer of separated basin
    arcpy.CopyFeatures_management('povodi_class', output_name)

    #check minimum bounding rectangle
    desc = arcpy.Describe(outputFeatureClassPath+'/'+output_name)
    shape_field_name = desc.ShapeFieldName
    rows3 = arcpy.SearchCursor(outputFeatureClassPath+'/'+output_name)

    mbr_X=[]
    mbr_Y=[]
    for row3 in rows3:
        
        # Create the geometry object
        feat = row3.getValue(shape_field_name)
        partnum = 0

        for pnt in feat.getPart(partnum):
            
            mbr_X.append(pnt.X)
            mbr_Y.append(pnt.Y)
                
            partnum += 1

    mbr_min_X=min(mbr_X)
    mbr_min_Y=min(mbr_Y)
    mbr_max_X=max(mbr_X)
    mbr_max_Y=max(mbr_Y)
    
    mbr_width = mbr_max_X - mbr_min_X
    mbr_high = mbr_max_Y - mbr_min_Y

    #define a grid start point position for basins smaller than map sheet
    grid_start_pnt_X = 0
    grid_start_pnt_Y = 0
    
    if mbr_width < sheet_width / 100 * scale: 
        grid_start_pnt_X = (mbr_min_X + mbr_width/2) - (sheet_width/100 * scale/2)        
        grid_start_pnt_Y = mbr_min_Y
        
    if mbr_high < sheet_high/100*scale:
        grid_start_pnt_Y = (mbr_min_Y + mbr_high/2) - (sheet_high/100 * scale/2)
        
        if mbr_width > sheet_width/100 *scale:
            grid_start_pnt_X = mbr_min_X
  
    #make a grid
    if (grid_start_pnt_X != 0) or (grid_start_pnt_Y != 0):
        arcpy.GridIndexFeatures_cartography(outputFeatureClassPath+'/'+grid_name, outputFeatureClassPath+'/'+output_name, "", "USEPAGEUNIT", scale_str, sheet_width_str, sheet_high_str, str(grid_start_pnt_X)+' '+str(grid_start_pnt_Y))
    else:
        arcpy.GridIndexFeatures_cartography(outputFeatureClassPath+'/'+grid_name, outputFeatureClassPath+'/'+output_name, "", "USEPAGEUNIT", scale_str, sheet_width_str, sheet_high_str)
    
    count_of_sheets_in_this_layer = int(arcpy.GetCount_management(outputFeatureClassPath+'/'+grid_name).getOutput(0))
    count_of_sheets.append(count_of_sheets_in_this_layer)

    #make fields of section number and page number
    arcpy.AddField_management(outputFeatureClassPath+'/'+grid_name, 'section', 'SHORT')

    arcpy.CalculateField_management(outputFeatureClassPath+'/'+grid_name, 'section', i)
    arcpy.AddField_management(outputFeatureClassPath+'/'+grid_name, 'GlobalPageName', 'TEXT')

    rows = arcpy.UpdateCursor(outputFeatureClassPath+'/'+grid_name)

    j=1
    for row in rows:
        row.PageNumber = page_number+j
        row.GlobalPageName = str(i)+'-'+row.PageName
        rows.updateRow(row)
        j+=1

    del rows, row
    page_number += count_of_sheets_in_this_layer

    merge_list.append(outputFeatureClassPath+'/'+grid_name)

    arcpy.CalculateAdjacentFields_cartography (outputFeatureClassPath+'/'+grid_name, "PageName")
    #add field with names of mapsheets into basins layer
    rows = arcpy.SearchCursor(outputFeatureClassPath+'/'+output_name)
    hard_IDs=[]
    basin_names=[]
    
    for row in rows:
        hard_IDs.append(row.hard_ID)
        fieldList = arcpy.ListFields(inFeatureClass, 'NADNAME') 
        fieldCount = len(fieldList)

        if (fieldCount == 1):
            basin_names.append(row.NADNAME)
        else:
            arcpy.AddWarning('Field with names not found!\nField with names of basins must name \"NADNAME\"')
    del rows, row
    
    for m in range(matchcount2):

        current_hard_ID = hard_IDs[m]
        current_name = basin_names[m]
        Query = "\"hard_ID\" = " + str(current_hard_ID)
        arcpy.SelectLayerByAttribute_management('povodi_class', "NEW_SELECTION", Query)
        
        #make feature layer
        arcpy.MakeFeatureLayer_management(outputFeatureClassPath+'/'+grid_name, 'grid_layer')
        arcpy.SelectLayerByLocation_management('grid_layer', 'intersect', 'povodi_class')

        text_string = ''
        n=0
        rows2 = arcpy.SearchCursor('grid_layer')

        for row2 in rows2:
            if n == 0:
                text_string = row2.PageName
                n+=1

            else:
                
                text_string = text_string+';'+row2.PageName
        del rows2, row2

        rows2 = arcpy.UpdateCursor(inFeatureClass)

        for row2 in rows2:
            if current_hard_ID == row2.hard_ID:
                row2.MapSheets = text_string
                rows2.updateRow(row2)
        del rows2, row2

        


#print RESULT
arcpy.AddMessage('\n ----- RESULT ----- \n Number of sections: '+str(i))
arcpy.AddMessage(' Number of map sheets...')
for j in range(len(count_of_sheets)):
    actuall_count = count_of_sheets[j]
    arcpy.AddMessage('      ... in section '+str(j+1)+': '+str(actuall_count)+'.')

arcpy.Merge_management(merge_list, outFeatureClass)
arcpy.Dissolve_management(outFeatureClass, outFeatureClass+'_dissolve', 'section')









