#!/bin/bash
# Resize new Firefox windows - For https://stackoverflow.com/q/66297454/1765658
# (C) 2023 - F-Hauri.ch
# Licensed by GNU GENERAL PUBLIC LICENSE Version 3
# Require: xdotool wmctrl and firefox

defaultUrl="https://stackoverflow.com/search?tab=votes&q=user%3A1765658+firefox"
defaultGeom=1200x900+200+120

usage() {
    dspchoice=("${!displays[@]}")
    printf -v dspchoice[0] '\47%s\47, ' "${dspchoice[@]:0:${#dspchoice[@]}-1}"
    cat <<-EOUsage
	Usage: ${0##*/} [-h] [ -g str | [ [ -p int | [-x int] [-y int] ] [-d str] [URL]
	    -d str  Display either ${dspchoice[0]%, } or '${dspchoice[@]: -1}'.
	    -g str  Geometry string in format 'WxH+X+Y' (must be alone).
	    -h      Show this.
	    -p int  Percent of display.
	    -x int  Percent width of display.
	    -y int  Percent height of display.
	    URL	    Default to '$defaultUrl'.
	EOUsage
}
die() { echo >&2 "${0##*/} ERR: $*"; exit 1;}    
mkBound() { local refstr=({0..9} _ {A..Z} '=' {a..z}) tfmt sfmt
    printf -v sfmt %8s ''
    tfmt=("${sfmt// /%s}"{,,}{,}) sfmt=${tfmt[*]} sfmt=${tfmt// /-}
    # shellcheck disable=SC2059
    printf -v bound "$sfmt" "${refstr[RANDOM%64]}"{,,}{,,,}{,,,}
}
getDispSize() {
    if [[ -v display ]];then
	[[ -v "displays[$display]" ]] || die "Can't found display '$display'."
	geometry=${displays[$display]}
    else
	if [[ -v displays[secondary] ]];then
	    ar=('' "${displays[root]}")
	    printf '%3d: %s (%s)\n' 1 Root whole\ display
	    while IFS=' x+' read -r dev stat a b c d e _; do
		if [[ $stat == connected ]]; then
		    typ=secondary
		    [[ $a == primary ]] &&
			typ=${a} a=$b b=$c c=$d d=$e
		    printf '%3d: %s (%s)\n' ${#ar[@]} "$dev" "$typ"
		    ar+=("${a}x$b+$c+$d")
		fi
	    done < <(LANG=C exec xrandr)
	    read -p 'Wich display: ' -rsn 1 userKey
	    if [[ ${ar[userKey]} ]]; then
		geometry=${ar[userKey]}
		echo "$userKey"
	    else
		echo user abort
		exit 1
	    fi
	else
	    geometry="${displays[root]}"
	fi
    fi	
}
splitGeom() {
    width=${geometry%%x*}
    height=${geometry#${width}x} height=${height%%[+-]*}
    xpos=${geometry#${width}x$height}
    [[ ${xpos%[+-]*} ]] && xpos=${xpos%[+-]*}
    ypos=${geometry#${width}x$height$xpos}
    [[ $xpos ]] || xpos=+0
    [[ $ypos ]] || ypos=+0
}
scaleGeom() {
    local _xpct=$1 _ypct=$2
    getDispSize
    splitGeom
    geometry=$(( width * _xpct / 100 ))x$(( height * _ypct / 100 ))+$((
	xpos + ( width - width * _xpct / 100 ) / 2 ))+$((
	ypos + ( height- height* _ypct / 100 ) / 2 ))
}
declare -A displays=()
while IFS=' x+' read -r cmd a ;do
    [[ $cmd == -geometry ]] && displays[root]=$a
done < <(LANG=C exec xwininfo -root)

while read -r dev state typ geom _; do
    if [[ $state == connected ]];then
	if [[ $typ == primary ]];then
	    displays[primary]="$geom"
	else
	    geom="$typ"
	    displays[secondary]="$geom"
	fi
	displays[$dev]="$geom"
    fi
done < <(LANG=C exec xrandr)

while getopts "hd:g:p:x:y:" opt;do
    case $opt in
        h ) usage; exit 0 ;;
        d ) [[ -v displays[$OPTARG] ]] || die "There is no '$OPTARG' display."
	    display=$OPTARG ;;
        g ) geometry=$OPTARG ;;
        p ) prct=$OPTARG ;;
        x ) xpct=$OPTARG ;;
        y ) ypct=$OPTARG ;;
        ? ) b=$((OPTIND-1)); die "'${!b}' not valid option." ;;
        * ) usage; die "opt: '$opt' ??" ;;
    esac
done
shift $((OPTIND-1))
targetUrl="${1:-$defaultUrl}"
if [[ -v geometry ]] ;then
    { [[ -v prct ]] || [[ -v ypct ]] || [[ -v xpct ]] ;} &&
	die "-g parm can't be used with any of -p -x or -y."
elif [[ -v prct ]] ;then
    { [[ -v ypct ]] || [[ -v xpct ]] ;} &&
	die "-p parm can't be used with any of -x or -y."
    scaleGeom "$prct" "$prct"
elif [[ -v xpct ]] ;then 
    scaleGeom "$xpct" "${ypct:-100}"
elif [[ -v ypct ]] ;then 
    scaleGeom 100 "$ypct"
else
    geometry="$defaultGeom"
fi

splitGeom

mkBound
printf -v ffurl "data:text/html;ascii,<head><title>%s</title></head>" "$bound"

firefox --new-window "$ffurl"

while ffwin=$(wmctrl -l|sed -ne "/$bound/s/ .*$//gp");[[ -z ${ffwin} ]] ;do
    echo -n .
    sleep .05
done
echo

xdotool windowraise "$ffwin"
xdotool windowfocus "$ffwin"
xdotool windowactivate "$ffwin"
xdotool windowsize "$ffwin" "$width" "$height"
xdotool windowmove "$ffwin" "$xpos" "$ypos"
xdotool windowsize "$ffwin" "$width" "$height"
xdotool windowmove "$ffwin" "$xpos" "$ypos"
xdotool windowactivate "$ffwin"
xdotool key ctrl+l

sleep .8

xdotool type --delay 22 "$targetUrl"
xdotool key Return