// SCRIPT LOGIC
// for site in sites:
    // for year in years:
        // register_images()


// VARIABLE DEFINITIONS
// images_to_register       =   All images to be registered for a given site and year (no target or seed)
// batch_images_to_register =   Batch images to be registered (no target or seed)
// batch_images_all         =   Target, seed and batch images to be registered 


var batch_size = 15;

var parent_dir = File($.fileName).parent.parent.fsName;
var batch_download_csv = File(parent_dir + "/coastsnap_sites.csv")
var site_name = "cooya"

// retreive site names from batch_download.csv
var csv_data=[];
batch_download_csv.open('r');
while(!batch_download_csv.eof){   
    var InputLine = batch_download_csv.readln(); 
    if(InputLine.length > 3) csv_data.push(InputLine);
}  
batch_download_csv.close();
var site_names = csv_data.toString().split(",")

// Retrieve images parent directory from CoastSnap_Sites.csv
var parent_folder_path = File(site_names[9]);

var batch_images_to_register = []; // Used in exportLayersToPNG

var site_path = parent_folder_path + "/" + site_name;

// Retrieve target and seed images for the site
var target_folder = new Folder(site_path + '/Target Image');
var seed_folder = new Folder(site_path + '/Target Image' + '/Seed Images');
var target_image = target_folder.getFiles("Target.jpg");
var seed_images = seed_folder.getFiles("*.jpg");

// Retrieve processed image years for the site
var processed_folder = new Folder(site_path + '/Processed');
var processed_subFolders = processed_folder.getFiles()

// Loop through years 
for (var j = 0; j < processed_subFolders.length; j++) {
    
    var year = processed_subFolders[j].name.toString();

    var processed_folder = new Folder(site_path + '/Processed/' + year);
    var photoshop_folder = new Folder(site_path + '/Photoshop/' + year);
    var processed_images_all = processed_folder.getFiles("*.jpg");
    var photoshop_images = photoshop_folder.getFiles("*.jpg");

    // Ignore images in processed that have already been registered
    var images_to_register = imagesNotRegistered(processed_images_all, photoshop_images);

    // Register images in batches, to avoid reaching the image limit that causes photoshop to crash
    for (var k = 0; k < images_to_register.length; k += batch_size) {
        batch_register_images(k, site_path, site_name, images_to_register, target_image, seed_images);
    } 
}



// This is the main function, responsible for calling photoshop functions
// in a sequential order to register all_images
function batch_register_images(batchIndex, site_path, site_name, images_to_register, target_image, seed_images) {

    var batch_images_all = [];
    batch_images_to_register = [];
    batch_images_all.push(target_image[0])

    for (var i = 0; i < seed_images.length; i++ ) {
        batch_images_all.push(seed_images[i]);
    }
    
    for (var i = batchIndex*1; i < batchIndex + batch_size; i++) {
        if(i < images_to_register.length) {
            batch_images_all.push(images_to_register[i]);
            batch_images_to_register.push(images_to_register[i].name);

        }
    }

    stackFiles(batch_images_all);
    resizeLayers();
    lockTarget();
    selectAllLayers();
    autoAlign();
    var target_size = cropToTarget();
    var target_width = target_size[0];
    var target_height = target_size[1];

    savePhotoshopDocument(site_path, site_name);
    exportLayersToPNG(target_width, target_height, batch_images_to_register, seed_images); // Won't overwrite images that already exist

    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
}


function imagesNotRegistered(site_images_all, photoshop_images) {
    
    var site_images = [];

    // Extract images that haven't been registered 
    for (var i = 0; i < site_images_all.length; i ++) { // For each site image
        var isRegistered = false;
        for (var j = 0; j < photoshop_images.length; j++ ) {  // Check if already exists in photoshop images    
            var site_name_CHECK = site_images_all[i].name.slice(0,-4) + '_CHECK.jpg';
            if((site_images_all[i].name.toString() == photoshop_images[j].name.toString()) || (site_name_CHECK.toString() == photoshop_images[j].name.toString())) {
                isRegistered = true;
                break;
            }
        }
        if(!isRegistered) { // If it doesn't, register it
            site_images.push(site_images_all[i]);
        }
    }  
    return site_images
}

function stackFiles(sFiles){  

    var loadLayersFromScript = true;  
    var SCRIPTS_FOLDER =  decodeURI(app.path + '/' + localize('$$$/ScriptingSupport/InstalledScripts=Presets/Scripts')); 
    $.evalFile( new File(SCRIPTS_FOLDER +  '/Load Files into Stack.jsx'));   
    loadLayers.intoStack(sFiles, false);  
    
};

function resizeLayers() {

    var doc = app.activeDocument;
    var targetImage = app.activeDocument.artLayers.getByName("Target.jpg")
    
    // Retrieve Target image dimensions
    var target_bounds = targetImage.bounds;
    var target_width = target_bounds[2] - target_bounds[0];
    var target_height = target_bounds[3] - target_bounds[1];
    
    // Update Target Image dimensions
    var new_width = 1280;
    preferences.rulerUnits = Units.PIXELS;
    var s = (new_width/target_width)*100;
    targetImage.resize(s, s, AnchorPosition.TOPLEFT)
    
    // Retrieve new Target image dimensions
    var target_bounds = targetImage.bounds;
    var target_width = target_bounds[2] - target_bounds[0];
    var target_height = target_bounds[3] - target_bounds[1];
    
    // Make layers similar dimensions to new Target
    var layerName = doc.layers;
    for (var ii = 0; ii < layerName.length; ii++) { //looping through all the layers
        var current_layer = layerName[ii];
        preferences.rulerUnits = Units.PIXELS;
        var b = current_layer.bounds;
        var layer_width = b[2]-b[0];
        var layer_height = b[3]-b[1];
        if (layer_height >= layer_width) {
            var s = (target_height/layer_height)*100;
        }
        else {
            var s = (target_width/layer_width)*100;
        }
        current_layer.resize(s, s, AnchorPosition.TOPLEFT)
    }
}

function selectAllLayers() {

    var desc = new ActionDescriptor();
    var ref = new ActionReference();
    ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc.putReference( charIDToTypeID('null'), ref );
    executeAction( stringIDToTypeID('selectAllLayers'), desc, DialogModes.NO );

};


function autoAlign() {

    var desc = new ActionDescriptor();
    var ref = new ActionReference();

    ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc.putReference( charIDToTypeID('null'), ref );
    desc.putEnumerated( charIDToTypeID('Usng'), charIDToTypeID('ADSt'), stringIDToTypeID('ADSContent') );
    desc.putEnumerated( charIDToTypeID('Aply'), stringIDToTypeID('projection'), charIDToTypeID('Auto') );
    desc.putBoolean( stringIDToTypeID('vignette'), false );
    desc.putBoolean( stringIDToTypeID('radialDistort'), false );

    executeAction( charIDToTypeID('Algn'), desc, DialogModes.NO );
        
};

function lockTarget() {
    var layerRef = app.activeDocument.artLayers.getByName("Target.jpg")
    layerRef.allLocked = true;
    app.activeDocument.activeLayer.linkedLayers
}


// CROP 
function cropToTarget() {
    var layerRef = app.activeDocument.artLayers.getByName("Target.jpg")
    app.activeDocument.crop(layerRef.bounds)
    var theBounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = theBounds[2] - theBounds[0];
    var layerHeight = theBounds[3] - theBounds[1];
    return [layerWidth, layerHeight];

}

// TO BE IMPLEMENTED
// function imageSize(layerRef) {

// }

// SAVE PHOTOSHOP DOCUMENT
function savePhotoshopDocument(site_path, site_name) {
    var PSdocumentFile = new File(site_path + '/' + site_name + '.psd');
    app.activeDocument.saveAs(PSdocumentFile)
}



// EXPORT LAYERS TO IMAGES

// $.evalFile(File(app.path + '/Presets/Scripts/Export Layers To Files.jsx'));
function exportLayersToPNG(target_width, target_height, batch_images_to_register, seed_images){
    if(!documents.length) return;
    var doc = activeDocument;
    var oldPath = activeDocument.path;
    
    var outFolder = new Folder(oldPath + "/Photoshop/" + year);
    if (!outFolder.exists) {
        outFolder.create();
    }
    
    scanLayerSets(doc);
    
    function scanLayerSets(el) {

        // // find layer groups
        // for(var a=0;a<el.layerSets.length;a++){
        //     var lname = el.layerSets[a].name;
        //     if (lname.substr(-4) == ".jpg") {
        //         saveLayer(el.layers.getByName(lname), lname, oldPath, true);
        //     } else {
        //         // recursive
        //         scanLayerSets(el.layerSets[a]);
        //     }
        // }
        
        var layerToRegister = true;
        // find plain layers in current group that are site images only (not target or seed)
        for(var j=0; j<el.artLayers.length; j++) { // Loop through photoshop document layers (images)
            var name = el.artLayers[j].name; 
            layerToRegister = true;

            // for (var i = 0; i < seed_images.length; i++ ) {
            //     if((seed_images[i].toString() == name.toString()) || (name.toString() == 'Target.jpg')) {
            //         layerToRegister = false;
            //     }
            // }
            // if(layerToRegister) {
                    
            //     app.activeDocument.activeLayer = el.layers.getByName(name);
            //     var theBounds = app.activeDocument.activeLayer.bounds;
            //     var aligned_image_width = theBounds[2] - theBounds[0];
            //     var aligned_image_height = theBounds[3] - theBounds[1];

            //     var name_updated = name;   
            //     // COMAPRE THE DIMENSIONS OF THE ALIGNED IMAGE WITH THE TARGET
            //     // IF SIGNIFICANT DIFFERENCE (30%), TAG IMAGE WITH '_CHECK.jpg'
            //     if((aligned_image_width/target_width) < 0.7 || (aligned_image_height/target_height) < 0.7) {
            //         name_updated = name.slice(0,-4) + '_CHECK.jpg';
            //     }

            //     saveLayer(el.layers.getByName(name), name_updated, oldPath, false);
            // }

            for (var i = 0; i < batch_images_to_register.length; i++ ) { // Loop through batch_images_to_register 
                if(batch_images_to_register[i].toString() == name.toString()) {
                    
                    app.activeDocument.activeLayer = el.layers.getByName(name);
                    var theBounds = app.activeDocument.activeLayer.bounds;
                    var aligned_image_width = theBounds[2] - theBounds[0];
                    var aligned_image_height = theBounds[3] - theBounds[1];

                    var name_updated = name;   
                    // COMAPRE THE DIMENSIONS OF THE ALIGNED IMAGE WITH THE TARGET
                    // IF SIGNIFICANT DIFFERENCE (30%), TAG IMAGE WITH '_CHECK.jpg'
                    // if((aligned_image_width/target_width) < 0.7 || (aligned_image_height/target_height) < 0.7) {
                    //     name_updated = name.slice(0,-4) + '_CHECK.jpg';
                    // }

                    saveLayer(el.layers.getByName(name), name_updated, oldPath, false);
                }
            }

        }
    
    }
    
    function saveLayer(layer, lname, path, shouldMerge) {
        activeDocument.activeLayer = layer;
        dupLayers();
        if (shouldMerge === undefined || shouldMerge === true) {
            activeDocument.mergeVisibleLayers();
        }
        //activeDocument.trim(TrimType.TRANSPARENT,true,true,true,true);
        var saveFile = File(path +"/Photoshop/"+year+"/"+lname);
        SavePNG(saveFile);
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    }
};
    
function dupLayers() { 
    var desc143 = new ActionDescriptor();
    var ref73 = new ActionReference();
    ref73.putClass( charIDToTypeID('Dcmn') );
    desc143.putReference( charIDToTypeID('null'), ref73 );
    desc143.putString( charIDToTypeID('Nm  '), activeDocument.activeLayer.name );
    var ref74 = new ActionReference();
    ref74.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc143.putReference( charIDToTypeID('Usng'), ref74 );
    executeAction( charIDToTypeID('Mk  '), desc143, DialogModes.NO );
};
    
function SavePNG(saveFile){
    var pngOpts = new ExportOptionsSaveForWeb; 
    pngOpts.format = SaveDocumentType.JPEG;
    pngOpts.PNG8 = false; 
    pngOpts.transparency = true; 
    pngOpts.interlaced = false; 
    pngOpts.quality = 100;
    activeDocument.exportDocument(new File(saveFile),ExportType.SAVEFORWEB,pngOpts); 
}