% function Methods
% This function runs through all locations, unpiling methods, plant sizes
% and available wood amounts to create a dataset. This dataset is then
% implemented into the HTL Excel file.

%% *REFERENCES*'

%[1] Ahmadinia, S., Palviainen, M., Kiuru, P., Routa, J., Sikanen, L., Urzainki, I., & Laurn, A. (Ari). (2022).
%Forest chip drying in self-heating piles during storage as affected by temperature and relative humidity conditions.
%Fuel, 324, 124419. https://doi.org/10.1016/j.fuel.2022.124419

%[2] Anerud, E., Larsson, G., & Eliasson, L. (2020).
%Storage of Wood Chips: Effect of Chip Size on Storage Properties.
%Croatian Journal of Forest Engineering, 41(2), 277286. https://doi.org/10.5552/crojfe.2020.663

%[3] Sahoo, K., Bilek, E. M. (Ted), & Mani, S. (2018).
%Techno-economic and environmental assessments of storing woodchips and pellets for bioenergy applications.
%Renewable and Sustainable Energy Reviews, 98, 27-39. https://doi.org/10.1016/j.rser.2018.08.055

clear all

%% Set location and distance
loc_opt = [1, 2, 3];
dist_opt = [10, 20, 30, 50, 75, 100, 120, 150, 200];
draw_opt = [5, 50, 100, 500, 1000, 2000, 4000, 6000, 8000];

%% Read variables from Excel

% Define the file name and sheet name
filename = '...Dataset.xlsx';

% Read content from Excel
sheetname = 'Initialize';
q = readmatrix(filename, 'Sheet', sheetname, 'Range', 'B1:B1');
timestep =readmatrix(filename, 'Sheet', sheetname, 'Range', 'B2:B2');
w_r = readmatrix(filename, 'Sheet', sheetname, 'Range', 'B3:B3');
max_time = readmatrix(filename, 'Sheet', sheetname, 'Range', 'B5:B5');
max_storage = readmatrix(filename, 'Sheet', sheetname, 'Range', 'B11:B11');
process_delay = readmatrix(filename, 'Sheet', sheetname, 'Range', 'B12:B12');

% Read contract info from Excel - Specify in Excel or in For Loop
%contract_type = string(readcell(filename,'Sheet',sheetname,'Range','B6:B6'));
%UL = readmatrix(filename,'Sheet',sheetname,'Range','B7:B7');
%LL = readmatrix(filename,'Sheet',sheetname,'Range','B8:B8');
UL_cost = readmatrix(filename,'Sheet',sheetname,'Range','B9:B9');
LL_cost = readmatrix(filename,'Sheet',sheetname,'Range','B10:B10');

for LL = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 3000, 5000, 7000, 10000, 25000, 50000, 75000, 100000, 125000, 150000, 175000, 200000]
    for UL = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 3000, 5000, 7000, 10000, 25000, 50000, 75000, 100000, 125000, 150000, 175000, 200000]
        for contract_type = ["Daily", "Weekly", "Monthly", "Yearly"]
            % Set contract counter
            filename = '...Dataset.xlsx';
            sheetname = 'Available Wood Waste';
            if contract_type == "Daily"
                period = ones(q,1);
            elseif contract_type == "Weekly"
                range = sprintf('%s%d:%s%d','AI',3,'AI', q+2);
                period = readmatrix(filename,'Sheet',sheetname,'Range',range);
            elseif contract_type == "Monthly"
                range = sprintf('%s%d:%s%d','AJ',3,'AJ', q+2);
                period = readmatrix(filename,'Sheet',sheetname,'Range',range);
            elseif contract_type == "Yearly"
                range = sprintf('%s%d:%s%d','AK',3,'AK', q+2);
                period = readmatrix(filename,'Sheet',sheetname,'Range',range);
            end

            for max_draw = draw_opt
                for loc = loc_opt
                    for dist = dist_opt
                        % Reset the file name and sheet name
                        filename = '...Dataset.xlsx';
                        % Set value of Feedstock In which is available to input
                        sheetname = 'Available Wood Waste';
                        if loc == 1
                            if dist == 10
                                %E3:E8768
                                range = sprintf('%s%d:%s%d','E', 3, 'E', q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 20
                                %F3:F8768
                                range = sprintf('%s%d:%s%d',col_num2str(6), 3, col_num2str(6), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 30
                                %G3:G8768
                                range = sprintf('%s%d:%s%d',col_num2str(7), 3, col_num2str(7), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 50
                                %H3:H8768
                                range = sprintf('%s%d:%s%d',col_num2str(8), 3, col_num2str(8), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 75
                                %I3:I8768
                                range = sprintf('%s%d:%s%d',col_num2str(9), 3, col_num2str(9), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 100
                                %J3:J8768
                                range = sprintf('%s%d:%s%d',col_num2str(10), 3, col_num2str(10), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 120
                                %K3:K8768
                                range = sprintf('%s%d:%s%d',col_num2str(11), 3, col_num2str(11), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 150
                                %L3:L8768
                                range = sprintf('%s%d:%s%d',col_num2str(12), 3, col_num2str(12), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 200
                                %M3:M8768
                                range = sprintf('%s%d:%s%d',col_num2str(13), 3, col_num2str(13), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end

                        elseif loc == 2
                            if dist == 10
                                %O3:O8768
                                range = sprintf('%s%d:%s%d',col_num2str(15), 3, col_num2str(15), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 20
                                %P3:P8768
                                range = sprintf('%s%d:%s%d',col_num2str(16), 3, col_num2str(16), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 30
                                %Q3:Q8768
                                range = sprintf('%s%d:%s%d',col_num2str(17), 3, col_num2str(17), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 50
                                %R3:R8768
                                range = sprintf('%s%d:%s%d',col_num2str(18), 3, col_num2str(18), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 75
                                %S3:S8768
                                range = sprintf('%s%d:%s%d',col_num2str(19), 3, col_num2str(19), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 100
                                %T3:T8768
                                range = sprintf('%s%d:%s%d',col_num2str(20), 3, col_num2str(20), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 120
                                %U3:U8768
                                range = sprintf('%s%d:%s%d',col_num2str(21), 3, col_num2str(21), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 150
                                %V3:V8768
                                range = sprintf('%s%d:%s%d',col_num2str(22), 3, col_num2str(22), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 200
                                %W3:W8768
                                range = sprintf('%s%d:%s%d',col_num2str(23), 3, col_num2str(23), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end

                        elseif loc == 3
                            if dist == 10
                                %Y3:Y8768
                                range = sprintf('%s%d:%s%d',col_num2str(25), 3, col_num2str(25), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 20
                                %Z3:Z8768
                                range = sprintf('%s%d:%s%d',col_num2str(26), 3, col_num2str(26), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 30
                                %AA3:AA8768
                                range = sprintf('%s%d:%s%d',col_num2str(27), 3, col_num2str(27), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 50
                                %AB3:AB8768
                                range = sprintf('%s%d:%s%d',col_num2str(28), 3, col_num2str(28), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 75
                                %AC3:AC8768
                                range = sprintf('%s%d:%s%d',col_num2str(29), 3, col_num2str(29), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 100
                                %AD3:AD8768
                                range = sprintf('%s%d:%s%d',col_num2str(30), 3, col_num2str(30), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 120
                                %AE3:AE8768
                                range = sprintf('%s%d:%s%d',col_num2str(31), 3, col_num2str(31), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 150
                                %AF3:AF8768
                                range = sprintf('%s%d:%s%d',col_num2str(32), 3, col_num2str(32), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                            if dist == 200
                                %AG3:AG8768
                                range = sprintf('%s%d:%s%d',col_num2str(33), 3, col_num2str(33), q+2);
                                og_input = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                            end
                        end

                        % Read moisture content as received
                        sheetname = 'Feedstock Properties';
                        if loc == 1
                            %D4:D8769
                            range = sprintf('%s%d:%s%d',col_num2str(4) , 4, col_num2str(4), q+3);
                            property_array = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        elseif loc == 2
                            %E4:E8769
                            range = sprintf('%s%d:%s%d',col_num2str(5) , 4, col_num2str(5), q+3);
                            property_array = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        elseif loc == 3
                            %F4:F8769
                            range = sprintf('%s%d:%s%d',col_num2str(6) , 4, col_num2str(6), q+3);
                            property_array = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        end

                        % Read yield properties
                        range = sprintf('%s%d:%s%d',col_num2str(7) , 4, col_num2str(11), q+3);
                        yield_array = readmatrix(filename, 'Sheet',sheetname,'Range',range);

                        % Find drying rate per [1]
                        sheetname = 'Weather Data';
                        if loc == 1
                            %F3:F9857
                            range = sprintf('%s%d:%s%d',col_num2str(6), 3, col_num2str(6), q+2);
                            k = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        elseif loc ==2
                            %J3:J9857
                            range = sprintf('%s%d:%s%d',col_num2str(10), 3, col_num2str(10), q+2);
                            k = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        elseif loc ==3
                            %N3:N9857
                            range = sprintf('%s%d:%s%d',col_num2str(14), 3, col_num2str(14), q+2);
                            k = readmatrix(filename, 'Sheet', sheetname, 'Range', range);
                        end

                        % Read fractional DML on a per day basis
                        sheetname = 'DML';
                        %E2:E1097
                        range = sprintf('%s%d:%s%d','E' , 3, 'E', q+2); %+1 to shift index to match Excel
                        DML = readmatrix(filename, 'Sheet', sheetname, 'Range', range);

                        % Initialize collected for pile_counter
                        if og_input(1) >= max_draw
                            collected = max_draw;
                        else
                            collected = og_input(1);
                        end

                        % Transpose matrices to match output size
                        max_input = max_draw*ones(1,q);
                        og_input = transpose(og_input);
                        property_array = transpose(property_array);
                        DML = transpose(DML);
                        k = transpose(k);
                        yield_array = transpose(yield_array);

                        %% Choose unpiling method
                        for a = 1:3
                            if a == 1
                                unpile = 'FIFO';
                                [collected, og_input, output_sum, feedstock_out, pile_size, trash_counter, trash_sum, moisture, cum_DML,pile_counter] = FIFO(period,UL,q,og_input,DML,max_time,max_draw,timestep,w_r,property_array,k,collected,max_storage,process_delay);
                            end
                            if a == 2
                                unpile = 'LIFO';
                                [collected, og_input, output_sum, feedstock_out, pile_size, trash_counter, trash_sum, moisture, cum_DML,pile_counter] = LIFO(period,UL,q,og_input,DML,max_time,max_draw,timestep,w_r,property_array,k,collected,max_storage,process_delay);
                            end
                            if a == 3
                                unpile = 'Homogeneous';
                                [collected, og_input, output_sum, feedstock_out, pile_size, trash_counter, trash_sum, moisture, cum_DML,pile_counter] = Homogeneous(period,UL,q,og_input,DML,max_draw,timestep,w_r,property_array,k,collected,max_storage,process_delay);
                            end


                            %% Calculate feedstock in sum
                            input_sum = zeros(q,1);
                            for index = 1:q
                                if index == 1
                                    input_sum(index) = og_input(index);
                                else
                                    input_sum(index) = input_sum(index-1) + og_input(index);
                                end
                            end
                            input_sum = transpose(input_sum);

                            %% Transpose all data to save to CSV file
                            %og_input; input_sum; feedstock_out; output_sum; pile_size; trash_counter; trash_sum; property_array; moisture; cum_DML;max_input;yield_array
                            og_input_t = transpose(og_input);
                            input_sum_t = transpose(input_sum);
                            feedstock_out_t = transpose(feedstock_out);
                            output_sum_t = transpose(output_sum);
                            pile_size_t = transpose(pile_size);
                            trash_counter_t = transpose(trash_counter);
                            trash_sum_t = transpose(trash_sum);
                            property_array_t = transpose(property_array);
                            moisture_t = transpose(moisture);
                            cum_DML_t = transpose(cum_DML);
                            max_input_t = transpose(max_input);
                            yield_array_t = transpose(yield_array);

                            %% Write to HTL file
                            savename = sprintf('...HTL_loc%d_dist%d_size%d_%s_%s_%dLL_%dUL_%d.xlsx',loc,dist,max_draw,unpile,contract_type,LL,UL,max_storage);
                            filename = savename; % This is used later to read the HTL file
                            template = 'HTL_Template.xlsx';
                            copyfile(template,savename)
                            column_names = ["Delivered", "Delivered Sum","Process Intake","Process Intake Sum","Pile Size", "Disposed Feedstock","Disposed Feedstock Sum","As Received Moisture","Process Intake Moisture","DML Sum","Max Intake Rate","Aq Sol Yield","Solid Residue","Gas Yield","Water Yield","Biocrude Yield"];
                            raw_data = [og_input_t, input_sum_t, feedstock_out_t, output_sum_t, pile_size_t, trash_counter_t, trash_sum_t, property_array_t, moisture_t, cum_DML_t, max_input_t, yield_array_t];
                            savedata = [column_names;raw_data];
                            writematrix(savedata,savename,'Sheet','Raw Data');

                            % Force HTL Excel spreadsheet to calculate
                            xlApp = actxserver('Excel.Application');
                            xlWorkbook =xlApp.workbooks.Open(savename);
                            xlWorkbook.Save;
                            xlWorkbook.Close;
                            xlApp.Quit;
                            delete(xlApp)

                            %% Write to Cost Model
                            % Create Cost Model File
                            savename = sprintf('...Cost_Model_loc%d_dist%d_size%d_%s_%s_%dLL_%dUL_%d.xlsm',loc,dist,max_draw,unpile,contract_type,LL,UL,max_storage);
                            template = 'Cost_Model_Template.xlsm';
                            copyfile(template,savename)

                            % Save location to Cost Model
                            if loc == 1
                                writematrix('Oregon',savename,'Sheet','Inputs', 'Range','G7')
                            elseif loc == 2
                                writematrix('Iowa',savename,'Sheet','Inputs', 'Range','G7')
                            elseif loc == 3
                                writematrix('Maryland',savename,'Sheet','Inputs', 'Range','G7')
                            end

                            % Save distance to Cost Model
                            % Do NOT double distance, account for near & far feedstock
                            if dist == 10
                                writematrix(10,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 20
                                writematrix(20,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 30
                                writematrix(30,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 50
                                writematrix(50,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 75
                                writematrix(75,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 100
                                writematrix(100,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 120
                                writematrix(120,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 150
                                writematrix(150,savename,'Sheet','Inputs', 'Range','G67')
                            elseif dist == 200
                                writematrix(200,savename,'Sheet','Inputs', 'Range','G67')
                            end

                            % Save draw_opt to Cost Model
                            writematrix(max_draw,savename,'Sheet','Inputs', 'Range','G8')

                            % Save contracts to Cost Model
                            writematrix(contract_type,savename,'Sheet','Inputs','Range','G112')
                            writematrix(UL,savename,'Sheet','Inputs','Range','G113')
                            writematrix(LL,savename,'Sheet','Inputs','Range','G114')
                            writematrix(UL_cost,savename,'Sheet','Inputs','Range','G115')
                            writematrix(LL_cost,savename,'Sheet','Inputs','Range','G116')

                            % Save Piling data to Cost Model
                            %C3:L[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(3), 3, col_num2str(12), q+2);
                            writematrix(raw_data,savename,'Sheet','Raw Data','Range',range)

                            % Read HTL file
                            %filename saved above
                            %D5:D[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(4), 5, col_num2str(4), q+4);
                            wet_feedstock = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %K5:K[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(11), 5, col_num2str(11), q+4);
                            added_solvent = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %Q5:Q[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(17), 5, col_num2str(17), q+4);
                            makeup_H2O = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %AI5:AI[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(35), 5, col_num2str(35), q+4);
                            biocrude_prod = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %AF5:AF[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(32), 5, col_num2str(32), q+4);
                            gas_prod = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %AG5:AG[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(33), 5, col_num2str(33), q+4);
                            solid_res = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %AK5:AK[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(37), 5, col_num2str(37), q+4);
                            sewer = readmatrix(filename,'Sheet','HTL Model','Range',range);
                            %AJ5:AJ[q+4]
                            range = sprintf('%s%d:%s%d',col_num2str(36), 5, col_num2str(36), q+4);
                            sewer_aq_sol = readmatrix(filename,'Sheet','HTL Model','Range',range);

                            % Write to Cost Model
                            %P3:P[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(16), 3, col_num2str(16), q+2);
                            writematrix(wet_feedstock,savename,'Sheet','Raw Data','Range',range);
                            %Q3:Q[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(17), 3, col_num2str(17), q+2);
                            writematrix(added_solvent,savename,'Sheet','Raw Data','Range',range);
                            %S3:S[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(19), 3, col_num2str(19), q+2);
                            writematrix(makeup_H2O,savename,'Sheet','Raw Data','Range',range);
                            %U3:U[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(21), 3, col_num2str(21), q+2);
                            writematrix(biocrude_prod,savename,'Sheet','Raw Data','Range',range);
                            %W3:W[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(23), 3, col_num2str(23), q+2);
                            writematrix(gas_prod,savename,'Sheet','Raw Data','Range',range);
                            %Y3:Y[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(25), 3, col_num2str(25), q+2);
                            writematrix(solid_res,savename,'Sheet','Raw Data','Range',range);
                            %AA3:AA[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(27), 3, col_num2str(27), q+2);
                            writematrix(sewer,savename,'Sheet','Raw Data','Range',range);
                            %AC3:AC[q+2]
                            range = sprintf('%s%d:%s%d',col_num2str(29), 3, col_num2str(29), q+2);
                            writematrix(sewer_aq_sol,savename,'Sheet','Raw Data','Range',range);

                            %% Run What-if Excel Analysis to find minimum sell cost
                            xlApp = actxserver('Excel.Application');
                            xlWorkbook = xlApp.Workbooks.Open(savename);
                            % Run the macro
                            macroName = 'PerformGoalSeek';
                            xlApp.Run(macroName);
                            % Save and close the workbook
                            xlWorkbook.Save;
                            xlWorkbook.Close;
                            xlApp.Quit;
                            delete(xlApp);

                            % If excel won't fully close, use the following:
                            %system('taskkill /F /IM excel.exe');
                            % Use only in emergency and in command window

                        end %ends unpiling loop
                    end %ends distance loop
                end %end location loop
            end %end plant sizing
        end %contract loop
    end % limit loop (UL)
end % limit loop (LL)