package main import math "core:math" import "core:fmt" import "core:strings" import "core:strconv" import "core:slice" // // --- STRUCTURES --- // Weekday : enum{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } Delta :: struct { minutes : int, hours : int, days : int, } Moment :: struct { minutes : int, hours : int, day : int, month : int, year : int, } Timeblock :: struct { start : Moment, end : Moment, valuefactor : f32, price_reason : string, } Workday :: struct { call : Moment, wrap : Moment, planned_wrap : Moment, blocks : [15]Timeblock, total_timeblocks : int, } // // --- BASIC OPERATIONS --- // windIndividual :: proc(input_moment: ^Moment, minutes: int, hours: int, days: int) { // Adding minutes input_moment.minutes += minutes for input_moment.minutes > 59 { input_moment.minutes -= 60 input_moment.hours += 1 } for input_moment.minutes < 0 { input_moment.minutes += 60 input_moment.hours -= 1 } // Adding hours input_moment.hours += hours for input_moment.hours > 23 { input_moment.hours -= 24 input_moment.day += 1 } for input_moment.hours < 0 { input_moment.hours += 24 input_moment.day -= 1 } // Adding days input_moment.day += days current_month_length: int = days_in(input_moment.month, input_moment.year) for input_moment.day > current_month_length { input_moment.day -= current_month_length input_moment.month += 1 if input_moment.month > 12 { input_moment.month -= 12 input_moment.year += 1 } current_month_length = days_in(input_moment.month, input_moment.year) } for input_moment.day < 1 { input_moment.month -= 1 if input_moment.month < 1 { input_moment.month += 12 input_moment.year -= 1 } current_month_length = days_in(input_moment.month, input_moment.year) input_moment.day += current_month_length } return } windDelta :: proc(moment: ^Moment, delta: Delta) { using delta wind(moment, minutes, hours, days) return } wind :: proc{windIndividual, windDelta} add :: proc(moment: Moment, delta: Delta) -> (output: Moment) { output = moment wind(&output, delta) return } sub :: proc(moment: Moment, delta: Delta) -> (output: Moment) { output = moment using delta wind(&output, minutes*-1, hours*-1, days*-1) return } gtMoment :: proc(moment_a: Moment, moment_b: Moment) -> bool { // TODO: This is wrong return true } gtDelta :: proc(delta_a: Delta, delta_b: Delta) -> bool { // TODO: This is wrong return true } gt :: proc{gtMoment, gtDelta} diff :: proc(moment_a: Moment, moment_b: Moment) -> (acc: Delta) { acc = {0, 0, 0} if moment_a == moment_b do return // Uses what I call an accumulator-decumulator design // Count how long it takes to approach a benchmark, // and that count is the difference reverse: bool = gt(moment_b, moment_a) // TODO: Finish writing this return } sortableTimeDelta :: proc(delta: Delta) -> int { using delta return strconv.atoi(fmt.tprintf("%2i%2i%2i", days, hours, minutes)) } sortableTimeMoment :: proc(moment: Moment) -> int { using moment return strconv.atoi(fmt.tprintf("%4i%2i%2i%2i%2i", year, month, day, hours, minutes)) } deltaToString :: proc(delta: Delta) -> (output: string) { using delta if hours == 0 && days == 0 && minutes == 0 { return "None" } cat_array : [dynamic]string printed_prev : bool = false if days>0 { buf: [5]byte append(&cat_array, fmt.tprint(days)) if days < 2 { append(&cat_array, " day") } else { append(&cat_array, " days") } printed_prev = true } if hours>0 { if printed_prev do append(&cat_array, ", ") buf: [5]byte append(&cat_array, fmt.tprint(hours)) if hours < 2 { append(&cat_array, " hour") } else { append(&cat_array, " hours") } printed_prev = true } if minutes>0 { if printed_prev do append(&cat_array, ", ") buf: [5]byte append(&cat_array, fmt.tprint(minutes)) if minutes < 2 { append(&cat_array, " minute") } else { append(&cat_array, " minutes") } } output = strings.concatenate(cat_array[:]) return } momentToString :: proc(moment: Moment) -> (output: string) { using moment cat_array: [dynamic]string output = fmt.tprintf("%i-%2i-%2i %2i:%2i", year, month, day, hours, minutes) return } timeblockToString :: proc(block: Timeblock) -> (output: string) { using block s: [3]string = {toString(start), " -> ", toString(end)} output = strings.concatenate(s[:]) return } toString :: proc{deltaToString, momentToString, timeblockToString} clockprintMoment :: proc(moment: Moment) -> string { using moment return fmt.tprintf("%2i:%2i", hours, minutes) } clockprintTimeblock :: proc(block: Timeblock) -> string { using block return fmt.tprintf("%s -> %s", timeprint(start), timeprint(end)) } timeprint :: proc{clockprintTimeblock, clockprintMoment} // // --- PROCEDURES --- // days_in :: proc(month: int, year: int) -> int { switch month { case 1: return 31; case 2: if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){ return 29; } return 28; case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; } fmt.printf("You just found month nr: %i. Something is very wrong.\n", month) assert(month < 13 && month > 0) return 30 } new_workday :: proc(previous_wrap : Moment, calltime : Moment, wraptime : Moment, planned_wraptime : Moment) -> (workday: Workday) { workday.call = calltime workday.wrap = wraptime workday.planned_wrap = planned_wraptime /* initial_block: Timeblock = { math.max( math.clamp(), ) } */ return }