﻿// Newest-Oldest

// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/endpoints/redirect.php?page=scripts for development information.

// Called by Directory Opus to initialize the script
function OnInit(initData) {
	initData.name = 'Newest-Oldest';
	initData.version = '1.0';
	initData.copyright = '(c) 2025 Christian Arellano García';
	initData.desc = '';
	initData.default_enable = true;
	initData.min_version = '13.19';
	AddConfig('log_level', DOpus.NewVector(2, 'debug', 'standard', 'warning', 'off'), 'Log level', 'Misc', 1, 'log level');

	function AddConfig(name, value, desc, group, g_order, label, min, max) {
		initData.config[name] = value;
		initData.config[name].desc = desc;
		initData.config[name].group = group;
		initData.config[name].group_order = g_order;
		if (label) initData.config[name].label = label;
		if (min !== undefined && min !== '') initData.config[name].min = min;
		if (max) initData.config[name].max = max;
	}
}
var EVI = {
	inf: undefined,
	GetNewest_Oldest: function(path, type, sort, prop, recursive) {
		var arr = ['', ''];
		if (!this.inf || !path) {
			Log(3, '=> No Everything Interface detected or path is not valid!');
			return arr;
		}
		var rec = !recursive ? (' depth:' + path.components) : '';
		var r = this.inf.Query('"' + path + '\\"' + rec + ' file:', '', 'f' + type, sort, 1);
		if (r.empty) return arr;
		arr[0] = r(0).fullpath;
		if (prop) arr[1] = r(0)[prop];
		// Log(1, 'Results: path:' + path + '; recursive:' + recursive + '; prop:' + prop + '; name:' + arr[0] + '; date:' + arr[1]);
		r = null;
		return arr;
	},
};
// Called to add columns to Opus
function OnAddColumns(addColData) {
	AddColumn('newest_created', 'Newest File Date Created', 'datetime');
	AddColumn('oldest_created', 'Oldest File Date Created', 'datetime');
	AddColumn('newest_created_name', 'Newest File Created');
	AddColumn('oldest_created_name', 'Oldest File Created');
	AddColumn('newest_created_recursive', 'Newest File Date Created (Rec)', 'datetime');
	AddColumn('oldest_created_recursive', 'Oldest File Date Created (Rec)', 'datetime');
	AddColumn('newest_created_name_recursive', 'Newest File Created (Rec)');
	AddColumn('oldest_created_name_recursive', 'Oldest File Created (Rec)');
	AddColumn('newest_modified', 'Newest File Date Modified', 'datetime');
	AddColumn('oldest_modified', 'Oldest File Date Modified', 'datetime');
	AddColumn('newest_modified_name', 'Newest File Modified');
	AddColumn('oldest_modified_name', 'Oldest File Modified');
	AddColumn('newest_modified_recursive', 'Newest File Date Modified (Rec)', 'datetime');
	AddColumn('oldest_modified_recursive', 'Oldest File Date Modified (Rec)', 'datetime');
	AddColumn('newest_modified_name_recursive', 'Newest File Modified (Rec)');
	AddColumn('oldest_modified_name_recursive', 'Oldest File Modified (Rec)');

	function AddColumn(name, label, type) {
		var col = addColData.AddColumn();
		col.name = name;
		col.method = 'OnNewestOldest';
		col.label = label;
		if (type) col.type = type;
		col.justify = type ? 'right' : 'left';
		col.autogroup = true;
		col.multicol = true;
		col.autorefresh = true;
	}

}

// Implement the Newest-Oldest column
function OnNewestOldest(scriptColData) {
	var item = scriptColData.item;
	if (!item) return;
	if (!item.is_dir) return '';
	StartEVI();

	if (!EVI.inf) return '';
	var col = scriptColData.col;
	var isRecursive = col.indexOf('recursive') !== -1;
	var type = col.indexOf('created') !== -1 ? 'c' : 'm';
	var isNewest = col.indexOf('newest') !== -1;

	var sort = type === 'c' ?
		(isNewest ? 12 : 11) :
		(isNewest ? 14 : 13);

	var prop = type === 'c' ? 'create' : 'modify';

	// Log(1, item.name + ':' + col);

	var data = EVI.GetNewest_Oldest(item.realpath, type, sort, prop, isRecursive);

	var timeType = type === 'c' ? 'created' : 'modified';
	var ageType = isNewest ? 'newest' : 'oldest';
	var recursiveSuffix = isRecursive ? '_recursive' : '';

	var dateColumn = ageType + '_' + timeType + recursiveSuffix;
	var nameColumn = ageType + '_' + timeType + '_name' + recursiveSuffix;;
	var cols = scriptColData.columns;

	SetColValue(dateColumn, data[1]);
	SetColValue(nameColumn, data[0]);

	function SetColValue(name, value) {
		if (!cols.Exists(name)) return;
		// Log(1, '=> Setting column "' + name + '" : ' + value);
		cols(name).value = value;
	}
}

function StartEVI() {
	if (EVI.inf !== undefined) return;
	var ev = DOpus.Create().EverythingInterface();
	var sw = false;
	Log(2, 'Starting Everything Interface...');
	Log(1, '=> is running:' + ev.isrunning + '; autorun:' + ev.autorun);
	if (!ev.isrunning && ev.autorun) {
		Log(2, '=> Starting Everything...');
		sw = ev.start(2000);
		DOpus.Delay(50);
	}
	else sw = true;
	if (!sw) {
		EVI.inf = null;
		return;
	}

	var attempt = 0;
	var loaded;
	Log(2, '=> Waiting for EV database...');
	do {
		loaded = ev.SendCmd(401); //wait for database
		if (loaded == 1) {
			Log(2, '==> Succesfully loaded...');
			break;
		}
		DOpus.Delay(10);
		attempt++;
		if (attempt === 150) {
			Log(3, ' ==> Max attempts waiting for the database has reached!');
			sw = false;
			break;
		}
	} while (true);
	EVI.inf = sw ? ev : null;
}

function Log(level, text) {
	if (level === 4 || Script.config.log_level < level) {
		if (level == 1) DOpus.Output('<#%vs_dragdrop_normal_action>DEBUG   => ' + text + '</#>');
		else if (level == 2) DOpus.Output('INFO    => ' + text);
		else if (level === 3) DOpus.Output('<#%vs_dragdrop_warning_action>WARNING => ' + text + '</#>');
		else DOpus.Output('ERROR   => ' + text, true);
	}
}