proc onmeshCartBFLoad {} {
    meshAutoDEZ onmeshCartLoad
}

proc aie_update_cart_preview {} {
    global beta_mode
    
    if !$beta_mode return
    if {([meshAutoDEZ get save_uns] == 0) && ([meshAutoDEZ get RefMethod] == 1)} {
	    ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartPreview 0
    } else {
	    ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartPreview 1
    }
}

proc onGlobalRefDDModify {dez val} {
    if { [meshAutoDEZ get RefMethod] == "Unstructured"} {
	    ::AIEnv::GUIManagement::ToggleGrey globalSaveUns 1
	    ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartPreview 1	
    } else {
	    ::AIEnv::GUIManagement::ToggleGrey globalSaveUns 0
	    ::AIEnv::GUIManagement::ToggleGrey mxzGlobalCartPreview 0
    }
    aie_update_cart_preview
}

proc onmeshCartInit {} {
    global beta_mode
    
    if ![info exists initMethodList] {
        set initMethodList {"Bounding Box" "Diagonal Points" "Key Points"}
        set initMethodList2 {"Bounding Box" "Diagonal Points"}
        set editList {"Add Stations" "Delete Stations" "Edit Stations" "Edit Ranges"}
        set editList2 {"Edit Stations"}
        set RefMethod 0
        if $beta_mode {
            onGlobalRefDDModify meshAutoDEZ 0
        }
        set cart_method 0
        set proj_factor 0.55
        set grid_split 0
        set inf_method 0
    }
}

proc onmeshCartLoad {} {
    global file_name cartfile_grid_type beta_mode
    
    if {$volmesh_type != 2} return
    set PartList [aie_list_parts 1]
    lappend PartList inherited
    if [llength [ic_geo_get_objects body]] {
        set vol_fam "inherited"
    }
   
    onmeshCartInit
    set kpt_tol 0.0
    
    if !$beta_mode {
        set cart_method 0
    }

    if ![ic_geo_is_loaded] {
        msg ERROR "No geometry loaded"
        return
    }
    if ![info exists input_file] {
        set input_file $file_name(tetin)
    }
    if {(![info exists min_size]) || $file_name(tetin) != $input_file} {
        set bbox [ic_geo_model_bounding_box]
        set bmin [lindex $bbox 0]
        set bmax [lindex $bbox 1]
        set lmax 0.0
        foreach i {0 1 2} {
            set l [expr [lindex $bmax $i] -  [lindex $bmin $i]]
            if {$l > $lmax} {
            set lmax $l
            }
        }
        set input_file $file_name(tetin)
        set xcut  [expr ([lindex $bmin 0]) + 0.5 * ([lindex $bmax 0] -  [lindex $bmin 0])]
        set ycut  [expr ([lindex $bmin 1]) + 0.5 * ([lindex $bmax 1] -  [lindex $bmin 1])]
        set zcut  [expr ([lindex $bmin 2]) + 0.5 * ([lindex $bmax 2] -  [lindex $bmin 2])]
    }
    if $cart_method {
        set cartfile_visible 1
        if ![ic_cart_is_loaded] {	
            cartfile_initialize
        }
        set ::cartfile_grid_type cartesian
        ic_cart_visible 1
    } else {
        set cartfile_visible 0
        ic_cart_visible 0
    }
}

proc onmeshCartAfterLoad {} {
    if ![info exists inf_method] {
        set inf_method 0
    }
}

proc onmeshCartGlobalLoad {} {
    global beta_mode
    
    if !$beta_mode return

    if !$cart_method {
        set cart_method 0
    }
    set cartfile_visible 1
    if ![ic_cart_is_loaded] {	
        cartfile_initialize
    }
    set ::cartfile_grid_type cartesian
    ic_cart_visible 1
}

proc onmeshCartGlobalUnLoad {} {
    set cartfile_visible 0
    ic_cart_visible 0
}

proc onmeshCartUnLoad {} {
    set cartfile_visible 0
    ic_cart_visible 0
}

proc onmeshCartBBoxFinish {} {    
    if {[llength $cart_bbox] == 2} {
        set pts ""
        foreach i {0 1} {
            set xyz [ic_geo_get_point_location [lindex $cart_bbox $i]]
            lappend pts $xyz
        }
        set cart_bbox [join $pts]
    }
}

proc aie_compute_cartesian_mesh {} {
    global file_name beta_mode env

    if {(![info exists env(AI_ENV_BFCART)] && ![info exists env(AI_ENV_GLOBAL)]) || [info exists env(AI_ENV_ACADEMIC)]} {
       msg ERROR "Can not run this application with this Licensing"
       return
    }
    if ![ic_geo_is_loaded] {
        msg ERROR "No geometry loaded"
        return
    }
    if {$file_name(tetin) == "" || [ic_geo_is_modified]} {
        aie_saveas_geom
    }
    if {$file_name(tetin) == ""} {
        set file_name(tetin) untiteled.tin
        aie_save_geom	
    }
    set input_file $file_name(tetin)
    
    if !$beta_mode {
        set cart_method 0
    }
    
    # set size info
    set do_autosizing 1
    if $grid_split {
        set do_autosizing 0
    }

    if $do_autosizing {
        if [aie_autosizing Shrinkwrap 1] {
            mess "Canceled by user\n" red
            return
        }
    }
    set gmax 0
    foreach {u v} [ ic_get_meshing_params global 0 ] {
        if {$u == "gmax"} {
            if {$v != ""} {set gmax $v}
            break
        }
    }

    set min_size $gmax
    if $do_autosizing {
        aie_no_autosizing
    }

    aie_get_global_mesh_params cur_mesh_params 
     
    if {$cart_method == 0} {	
	    if {$vol_fam == ""} {
	        if {[ic_list_volume_families] != ""} {
		        set vol_fam inherited
	        } else {
		        set vol_fam CREATED_MATERIAL
	        }
	    }
	    set fam $vol_fam
	    if {$vol_fam != "inherited"} {
	        set fam [aie_new_part $vol_fam]
	    }
	    ic_undo_suspend
	    set args "\"$file_name(tetin)\" $min_size $fam"
	    if $cur_mesh_params(cart_split_degen) {
	        append args " split_degen 1"
	    }
	    if $cur_mesh_params(cart_create_pyramids) {
	        append args " create_pyramids 1"
	    }
	    append args " proj_factor $cur_mesh_params(cart_proj_factor)"	
	    append args " tratio [aie_cart_reftype $cur_mesh_params(cart_tratio)]"
	    if {($cur_mesh_params(cart_user_bbox)) && $cur_mesh_params(cart_bbox) != ""} {
	        set bbox [list [join $cur_mesh_params(cart_bbox)]]
	        append args " bbox $bbox" 
	        append args " type 1" 
	    }	
	    if $cur_mesh_params(cart_csys) {
	        set csys [ic_csystem_get_current]
	        if {$csys == "global"} {
		        msg ERROR "No Local Coordinate System is active"
		        return
	        }
	        set csys_type [lindex [ic_csystem_get $csys] 0]
	        if {$csys_type != "cartesian"} {
		        msg ERROR "Non-Cartesian local coordinate system not fully supported"
	        }
	        append args " csys $csys"
	    }
	    if $cur_mesh_params(cart_conformal) {
	        append args " conformal 1"
	    }
	    set aspect_ratio [list [join $cur_mesh_params(cart_aspect_ratio)]]
	    append args " aspect_ratio $aspect_ratio" 
	
	    if ![string is integer -strict $grid_split] {
	        mess "Missing value for \"Split type\"\n" red
	        return
	    }
	    if { $grid_split > 0 && $grid_split < 3 && $gridFile != "" } {
	        append args " gridfile \"$gridFile\""
	    }
	    if {$grid_split > 1} {
	        append args " feature_split 1"
	    }
	    append args " nuntangle $cur_mesh_params(cart_nuntangle)"
	    set inf [expr ($inf_method+1)%3]
	    if $inf {
	        append args " inflate $inf"
	        if $cur_mesh_params(cart_infproj) {
		        append args " infproj 1"
	        }
	    }
	    set maxref $cur_mesh_params(cart_maxref)
	    if { $maxref > -1 } {
	        append args " maxref $maxref"
	    }
	    if { $kpt_tol > 0.0 } {
	        append args " kpt_tol $kpt_tol"
	    }
	    eval ic_hexcart_body_fitted $args
	    ic_undo_resume
	    return
    }

    set pref [file tail [file rootname $file_name(settings)]]    
    if {$pref == "" && $file_name(cart_file) == ""} {
	    set file_name(cart_file) "[file root [file tail $input_file]].crt"
    }
    
    set cart_file [aie_save_cart]
    if {$cart_file == ""} {
	    return
    }

    set cart_meshfile "[file root [file tail $file_name(tetin)]].cartmesh"
    # mesher will automatically do internal/external
    set type 3

    set out_file temp_cart.uns

    set vof -1
    if $cur_mesh_params(cart_computevof) {
	    set vof $cur_mesh_params(cart_volfrac)
    }
    
    if {$RefMethod == 1} {	
	    set pure_cart 1
    } else {
	    set pure_cart 0
    }

    set stat [ic_mesh_hexcart \
		  tetin $input_file \
		  gridfile $cart_file \
		  cartfile $cart_meshfile \
		  outfile  $out_file \
		  minsize  $min_size \
		  maxref   $cur_mesh_params(cart_maxref) \
		  start    $cur_mesh_params(cart_nStart) \
		  nlayers  $cur_mesh_params(cart_nlayers) \
		  uniform  $cur_mesh_params(cart_refall) \
		  type $type \
		  pure_cart $pure_cart \
		  cart_uns $save_uns \
		  xcut $xcut \
		  ycut $ycut \
		  zcut $zcut \
		  symx $cur_mesh_params(cart_symx) \
		  symy $cur_mesh_params(cart_symy) \
		  symz $cur_mesh_params(cart_symz) \
		  volfrac $vof \
		  create_faces $cur_mesh_params(cart_faces)  \
		  create_edges $cur_mesh_params(cart_edges)]

    if $stat {
        set file_name(domain) $out_file
        if ![aie_open_Mesh 0] {
            return
        }
        aie_afterStuffLoaded
	    set file_name(cart_meshfile) $cart_meshfile
    }
}

proc onGlobalInit2DDModify {dez val} {
    onGlobalInitDDModify $dez $val
}

proc onGlobalInitDDModify {dez val} {
    if {$val == "Bounding Box"} {
	cartfile_initialize
    } elseif {$val == "Diagonal Points"} { 
	set pts [geo_select point 2 "Select 2 diagonal points"]
	if {[llength $pts] != 2} {
	    msg ERROR "2 points requied"
	    return
	}
	set ptlocs ""
	foreach pt $pts {
	    lappend ptlocs [ic_geo_get_point_location $pt]
	}
	cartfile_initialize $ptlocs
    } elseif {$val == "Key Points"} {
	cartfile_reset
    } else {
	msg ERROR "Invalid method for Global Initialization"
    }
}

proc onGlobalEdit2DDModify {dez val} {
    onGlobalEditDDModify $dez $val
}

proc onGlobalEditDDModify {dez val} {
    switch $val {
	"Add Stations"    { cartfile_add_stations }
	"Delete Stations" { cartfile_del_stations }
	"Edit Stations"   { cartfile_edit_stations }
	"Edit Ranges"     { cartfile_edit_ranges }
	default { 
	    msg ERROR "Invalid method for Global grid editing"
	}
    }
}

proc aie_cart_reftype {reftype_name} {
    switch $reftype_name {
	"Uniform" {set reftype 1}
	"2-to-1" {set reftype 2}
	"3-to-1" {set reftype 3}
	default {
	    mess "Error: reftype $reftype_name not supported\n" red
	    set reftype 0
	}
    }

    return $reftype
}

