function [tikz_link] = Viterbi_Convolutionalcode_Trellis_UserInput(uploadpolys, decoding, uploadsequence, trellissegments, vit_switch, cwbitswitch, pathmetricswitch, inue_js_animationNumberOfFrames, filename)

% input generator polynomials
gp_oct = dlmread(uploadpolys,",",0,0);
gp_oct=gp_oct';
gp_octal(:,:)=num2str(gp_oct(:,:));
gp_octal(gp_octal==" ") = "0";

% input sequence
switch(decoding)
case 1
 received_sequence = dlmread(uploadsequence,",",0,0);
 seq = 1;
case 0
 received_sequence = zeros(trellissegments,size(gp_oct));
 seq = 0; 
endswitch
 
% input viterbi algorithm hard or soft
switch(vit_switch)
  case "hard" % harddescision
    viterbi_switch = 0;
  case "soft" % softdescision
    viterbi_switch = 1;
endswitch

code_string =  "user input";  

% general trellis structures
for i=1:size(gp_octal,1); 
gp_bit_string{i,1} = octstr2bitstr(strcat(gp_octal(i,:)));
end
gp_bits = pad_leading_zeros(gp_bit_string);
states_amount = 2^(length(gp_bits{1,1})-1); 
received_amount = ((size(received_sequence))(2));
segments_amount = ((size(received_sequence))(1));
time_instances = segments_amount+1;
states = states_cell_array(states_amount);
state_transitions = state_transitions(states); %state_transitions{i,l} i:states, l=1:"zero"-transition; l=2:"one"-transition
codewortbit_edge_outputs = edge_outputs_array(states,gp_bits); %codewortbit_edge_outputs(i,k,l) i:states, k:sequence bits, l=1:"zero"-transition; l=2:"one"-transition

% the following steps will only be executed if decoding is wanted
if seq == 1

path_metric_array = 1000*ones(states_amount, time_instances);
path_metric_array(1,1) = 0;
edge_metric = 0;

%% possible conditions of entrys and lifespan:
deadtransition = 0;
livingtransition = 1;
stillalive = 8888;
stillborn = 9999;
nonexistent = 1000;

entrys = 1000*ones(states_amount,4,segments_amount);  % condition of entering paths into states through trellis per time instance  
%% Columns: 1:condition_In_1 2:Origin_o_In_1 3:condition_In_2 4:Origin_of_In_2 
%% Entry colums 1;3:   0:transition_dead 1:transition_alive 1000:transition_non-existent 

lifespan = 1000*ones(states_amount,2,segments_amount); % lifespan of entering paths in segments        
%% Columns: 1:dead_of_1 2:dead_of_2 
%% Entry colums 1;2:   x:time_instance_of_dead 1000:transition_non-existent 8888:stillalive 9999:stillborn

exits = zeros(states_amount,2,segments_amount); % exits of states per time instance
%% Columns: 1:exit_sum 2:dead_count; 

% adjust received sequence in case of hard descision viterbi
if viterbi_switch == 0
  for i = 1:segments_amount
    for j = 1:received_amount
      if received_sequence(i,j) > 0
        received_sequence(i,j) = 1;
      else 
        received_sequence(i,j) = 0;
      end
    end
  end
end

%% viterbi algorithm
for j = 1:segments_amount 
  for i = 1:states_amount 
    for l = 1:2;  % l=1: "zero"-transition ; l=2: "one"-transition
      % calculate transition edge_metric
      for k =1:received_amount
        if received_sequence(j,k) ~= codewortbit_edge_outputs(i,k,l) 
          if viterbi_switch == 0
            edge_metric = edge_metric+1;
          elseif viterbi_switch == 1
            if codewortbit_edge_outputs(i,k,l) == 0
              c = -1;
            else 
              c = 1;
            end 
            edge_metric = edge_metric+(received_sequence(j,k)-(c))^2;
          end
        end
      end
      edge_metric = path_metric_array(i,j) + edge_metric;
      % save calcualted transition as first, second or only survivor or as dead
      arrival_state = state_transitions{i,l}+1;
      if (path_metric_array(arrival_state,j+1) > edge_metric) && (path_metric_array(arrival_state,j+1) == 1000) % 1st alive transition to state arrival_state found
        path_metric_array(arrival_state,j+1) = edge_metric;
        entrys(arrival_state,1,j+1) = 1;
        entrys(arrival_state,2,j+1) = i;
        exits(i,1,j) = exits(i,1,j)+1;
        lifespan(arrival_state,1,j) = stillalive;
      elseif path_metric_array(arrival_state,j+1) == edge_metric && (path_metric_array(arrival_state,j+1) < 1000)% 2nd alive transition to state arrival_state found
        entrys(arrival_state,3,j+1) = 1;
        entrys(arrival_state,4,j+1) = i;
        exits(i,1,j) = exits(i,1,j)+1;
        lifespan(arrival_state,2,j) = stillalive;
      elseif (path_metric_array(arrival_state,j+1) > edge_metric) && (path_metric_array(arrival_state,j+1) < 1000) % new better alive transition found, other transition dies
        path_metric_array(arrival_state,j+1) = edge_metric;
        entrys(arrival_state,1,j+1) = 0;
        entrys(arrival_state,3,j+1) = 1;
        entrys(arrival_state,4,j+1) = i;
        exits(i,1,j) = exits(i,1,j)+1;
        exits(entrys(arrival_state,2,j+1),2,j) = exits(entrys(arrival_state,2,j+1),2,j)+1; 
        lifespan(arrival_state,1,j) = stillborn;
        lifespan(arrival_state,2,j) = stillalive;
      elseif (path_metric_array(arrival_state,j+1) < edge_metric) && (path_metric_array(arrival_state,j+1) < 1000) && (path_metric_array(i,j) < 1000) % dead transition found
        entrys(arrival_state,3,j+1) = 0;
        entrys(arrival_state,4,j+1) = i;
        exits(i,1,j) = exits(i,1,j)+1;
        exits(i,2,j) = exits(i,2,j)+1;
        lifespan(arrival_state,2,j) = stillborn;
      end
      edge_metric = 0;
    end
  end 
  % adapt depending dead transitions in prior trellis
  if j > 2
    for m = j:-1:2 
      for i = 1:states_amount
        % compare amout of exitsum and amount of dead exits in each earlier state to find dead transitions
        if (exits(i,1,m) == exits(i,2,m)) && (exits(i,1,m)>0)
          if entrys(i,1,m) == 1
            entrys(i,1,m) = 0;
            exits(entrys(i,2,m),2,m-1) = exits(entrys(i,2,m),2,m-1)+1;
            lifespan(i,1,m-1) = j-1;
          end
          if entrys(i,3,m) == 1
            entrys(i,3,m) = 0;
            exits(entrys(i,4,m),2,m-1) = exits(entrys(i,4,m),2,m-1)+1;
            lifespan(i,2,m-1) = j-1;
          end
        end
      end
    end
  end  
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   T I K Z   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% constants
states_num_string = num2str(states_amount-1);
seg_num_string = num2str(segments_amount-1);
t_i_num_string = num2str(time_instances-1);

% begin & end
tikz_begin = "\n%%%%%%%%%%%%%%%%%%% T I K Z   S E T T I N G S %%%%%%%%%%%%%%%%%%%\n\n\n% you can adjust your trellis by changing styles and values\n\\documentclass[crop,beamer]{standalone}\n\\usepackage{tikz}\n\\begin{document}\n\\usetikzlibrary{decorations.shapes,calc}\n\\begin{frame}\n\\resizebox{10.8cm}{!}{\n\\begin{tikzpicture}\n% change 'tikzstyle's to personalize the appearance of trellis elements";
tikz_end = "\n\n\\end{tikzpicture}\n}\n\\end{frame}\n\\end{document}"; 

if segments_amount < 3
  fontsize = "\\normalsize";
elseif segments_amount > 5
  fontsize = "\\tiny";
else
  fontsize = "\\scriptsize";
end

x_scale = 9.4/(segments_amount-1);
if states_amount > 4
y_scale = 9.4/(states_amount-1);
tikz_styles = strcat("\n\\tikzstyle{every node}=[font=",fontsize,"]\n\\tikzstyle{dots}=[draw,circle,inner sep=0.7pt,fill=black!50]\n\\tikzstyle{pathszero}=[thin,black,dashed,-]\n\\tikzstyle{pathsone}=[thin, red,-]\n\\tikzstyle{livingpathoutline}=[thick,red,double=red!20,double distance=2pt,join=round,cap=round]\n\\tikzstyle{deadpathoutline}=[thick,black,double=black!20,double distance=2pt,join=round,cap=round]");
elseif states_amount < 3
y_scale = (9.4/(states_amount-1))/3;
tikz_styles = strcat("\n\\tikzstyle{every node}=[font=",fontsize,"]\n\\tikzstyle{dots}=[draw,circle,inner sep=2pt,fill=black!50]\n\\tikzstyle{pathszero}=[very thick,black,dashed,-]\n\\tikzstyle{pathsone}=[very thick, red,-]\n\\tikzstyle{livingpathoutline}=[thick,red,double=red!20,double distance=6pt,join=round,cap=round]\n\\tikzstyle{deadpathoutline}=[thick,black,double=black!20,double distance=6pt,join=round,cap=round]");
else
y_scale = (9.4/(states_amount-1))/2;
tikz_styles = strcat("\n\\tikzstyle{every node}=[font=",fontsize,"]\n\\tikzstyle{dots}=[draw,circle,inner sep=1.4pt,fill=black!50]\n\\tikzstyle{pathszero}=[thick,black,dashed,-]\n\\tikzstyle{pathsone}=[thick, red,-]\n\\tikzstyle{livingpathoutline}=[thick,red,double=red!20,double distance=4pt,join=round,cap=round]\n\\tikzstyle{deadpathoutline}=[thick,black,double=black!20,double distance=4pt,join=round,cap=round]");
end
tikz_styles = strcat(tikz_styles,"\n\\tikzstyle{pathmetric}=[draw,circle,inner sep=2pt,fill=white,anchor=north east]");
tikz_styles = strcat(tikz_styles,"\n\\tikzstyle{codewordbits}=[rectangle, rounded corners=9pt, fill=white, fill opacity=.6, text opacity=1, text=black]");
tikz_styles = strcat(tikz_styles,"\n% change xscale, yscale and pathmetricposition to resize your diagram");
tikz_styles = strcat(tikz_styles,"\n\\def\\xscale{",num2str(x_scale),"}\n\\def\\yscale{",num2str(y_scale),"}");
tikz_styles = strcat(tikz_styles,"\n\\def\\segments{",seg_num_string,"} % =(amount of segments - 1)");
tikz_styles = strcat(tikz_styles,"\n\\def\\ti{",t_i_num_string,"} % =(amount of time instances - 1)");
tikz_styles = strcat(tikz_styles,"\n\\def\\pathmetricposition{",num2str(0.25),"}");
tikz_styles = strcat(tikz_styles,"\n\\def\\codewordbitsposition{",num2str(0.25),"}");
tikz_styles = strcat(tikz_styles,"\n% change '{1}' to '{0}' to avoid displaying decoding, pathmetric or codeword bits on trellis paths");
tikz_styles = strcat(tikz_styles,"\n\\def\\showdecoding{1}");
tikz_styles = strcat(tikz_styles,"\n\\def\\pathmetric{",num2str(pathmetricswitch),"}");
tikz_styles = strcat(tikz_styles,"\n\\def\\codewordbits{",num2str(cwbitswitch),"}");


% time instance
tikz_steps_start_string = "\n\n% time instance\n\\foreach \\x in {0,...,\\ti}{ \n\\draw (\\xscale*\\x,\\yscale*";
tikz_steps_end_string = ") node[anchor=south] {$t_{\\x}$};  \n}";
steps_string = strcat(tikz_steps_start_string,states_num_string,"+0.2",tikz_steps_end_string);

% dots
tikz_dots_start_string = "\n\n% dots\n\\foreach \\x in {0,...,\\ti}{\n\\foreach \\y in {0,...,";
tikz_dots_end_string = strcat("}{\n\\node[dots] at (\\xscale*\\x,\\yscale*\\y) {};    	\n}\n}");
dots_string = strcat(tikz_dots_start_string,states_num_string,tikz_dots_end_string);

% states
states_string = strcat("\n\n\n%%%%%%%%%%%%%%%%%%%%% T I K Z C O D E %%%%%%%%%%%%%%%%%%%%%\n\n% generator polynomials:", code_string, "\n\n\n\n% states ");
for i = 1:states_amount
state_string = num2str((states{i,1})(1));
if length(states{i,1})>1    
for j=1:((length(states{i,1}))-1)
  state_string = strcat(state_string,((states{i,1})(j+1)));
end
end
tikz_states_one_string = "\n\\draw (0,";
tikz_states_two_string = ") node[anchor=east] {$s_{";
tikz_states_three_string = "}\\,=\\,(";
tikz_states_four_string = ")$\\,\\,};";
states_string = strcat(states_string,tikz_states_one_string,"\\yscale*",num2str(-i),"+\\yscale*",num2str(states_amount),tikz_states_two_string,num2str(i-1), tikz_states_three_string,state_string,tikz_states_four_string);
end

% arrows
arrows_string = strcat("\n\n% arrows\n\\foreach \\x in {0,...,\\segments}{ ");
for i=1:states_amount
tikz_arrows_one_string = strcat("\n\\draw[pathsone](\\xscale*\\x,");
tikz_arrows_two_string = strcat(") -- (\\xscale*(\\x+1,\\yscale*floor(");
tikz_arrows_three_string = ");";
tikz_arrows_four_string = strcat(" \n\\draw[pathszero] (\\xscale*\\x,");
tikz_arrows_five_string = strcat(") -- (\\xscale*(\\x+1,");
tikz_arrows_six_string = ") ";
tikz_arrows_seven_string = "; ";
arrows_string = strcat(arrows_string,tikz_arrows_one_string,"\\yscale*",num2str(i-1),tikz_arrows_two_string,num2str((i-1)/2),tikz_arrows_three_string,tikz_arrows_four_string,"\\yscale*",num2str((states_amount-1)-(i-1)),tikz_arrows_five_string,"\\yscale*",num2str(ceil((states_amount-1)-((i-1)/2))),tikz_arrows_six_string,tikz_arrows_seven_string);
end
arrows_string = strcat(arrows_string,"\n}");

% codeword bits
codewordbits_string = strcat("\n\n% codeword bits\n\\if\\codewordbits0\n\\else\n\\foreach \\x in {0,...,\\segments}{ ");
for i=1:states_amount
edge_string_one = num2str(codewortbit_edge_outputs(states_amount+1-i,1,2));
edge_string_zero = num2str(codewortbit_edge_outputs(i,1,1));
if received_amount > 1    
for j=1:(received_amount-1)
  edge_string_zero = strcat(edge_string_zero,",",num2str(codewortbit_edge_outputs(i,j+1,1)));
  edge_string_one = strcat(edge_string_one,",",num2str(codewortbit_edge_outputs(states_amount+1-i,j+1,2)));
end
end   
codewordbits_one = strcat("\n\\node [codewordbits]at($(\\xscale*\\x,");
codewordbits_two = strcat(")!\\codewordbitsposition!(\\xscale*(\\x+1,\\yscale*floor(");
codewordbits_three = ")$) {(";
codewordbits_four = strcat(")}; \n\\node [codewordbits]at($(\\xscale*\\x,");
codewordbits_five = strcat(")!\\codewordbitsposition!(\\xscale*(\\x+1,");
codewordbits_six = ")$) {(";
codewordbits_seven = ")}; ";
codewordbits_string = strcat(codewordbits_string,codewordbits_one,"\\yscale*",num2str(i-1),codewordbits_two,num2str((i-1)/2),codewordbits_three,edge_string_one);
codewordbits_string = strcat(codewordbits_string,codewordbits_four,"\\yscale*",num2str((states_amount-1)-(i-1)),codewordbits_five,"\\yscale*",num2str(ceil((states_amount-1)-((i-1)/2))),codewordbits_six,edge_string_zero,codewordbits_seven);
end
codewordbits_string = strcat(codewordbits_string,"\n}\\fi ");

% TikZ code for decoding (only executed if decoding is wanted)
if seq == 1
% temporary path segments
decoding_path_string = "\n\n% temporary path segments \n\\if\\showdecoding0\n\\else ";
living_path_red = "\n \\draw[livingpathoutline] (";
dead_path_black = "\n \\draw[deadpathoutline] (";
only_string_1 = "\n\\only<";
only_string_2 = "-";
only_string_3 = ">{";
connection = ") -- (";
comma = ",";
path_end = ");";
only_end = "}";
%% trellis paths depending only on lifespans
for j = 1:segments_amount
for i = 1:states_amount
  origin_x_position = strcat("\\xscale*",num2str(j-1));
  arrival_x_position = strcat("\\xscale*",num2str(j));
  for k = 1:2
    p=2*k;
    if lifespan(i,k,j) != nonexistent
      origin_state = strcat("\\yscale*",num2str(states_amount),"-\\yscale*",num2str(entrys(i,p,j+1)));
      arrival_state = strcat("\\yscale*",num2str(states_amount),"-\\yscale*",num2str(i));
      birth = num2str(j);
      if lifespan(i,k,j) < stillalive
        obit = num2str(lifespan(i,k,j));
        death = num2str(lifespan(i,k,j)+1);
        decoding_path_string = strcat(decoding_path_string,only_string_1,birth,only_string_2,obit,only_string_3);
        decoding_path_string = strcat(decoding_path_string,living_path_red,origin_x_position,comma,origin_state,connection,arrival_x_position,comma,arrival_state,path_end);
        decoding_path_string = strcat(decoding_path_string,only_end);
        decoding_path_string = strcat(decoding_path_string,only_string_1,death,only_string_2,death,only_string_3);
        decoding_path_string = strcat(decoding_path_string,dead_path_black,origin_x_position,comma,origin_state,connection,arrival_x_position,comma,arrival_state,path_end);
        decoding_path_string = strcat(decoding_path_string,only_end);
      elseif lifespan(i,k,j) == stillalive
        decoding_path_string = strcat(decoding_path_string,only_string_1,birth,only_string_2,num2str(segments_amount+1),only_string_3);
        decoding_path_string = strcat(decoding_path_string,living_path_red,origin_x_position,comma,origin_state,connection,arrival_x_position,comma,arrival_state,path_end);
        decoding_path_string = strcat(decoding_path_string,only_end);
      elseif lifespan(i,k,j) == stillborn
        decoding_path_string = strcat(decoding_path_string,only_string_1,birth,only_string_2,birth,only_string_3);
        decoding_path_string = strcat(decoding_path_string,dead_path_black,origin_x_position,comma,origin_state,connection,arrival_x_position,comma,arrival_state,path_end);
        decoding_path_string = strcat(decoding_path_string,only_end);
      end
    end
  end
end
end
decoding_path_string = strcat(decoding_path_string,"\n\\fi ");

% received sequence
sequence_string = strcat("\n\n% received sequence\n\\if\\showdecoding0\n\\else \n\\\draw (0,\\yscale*",states_num_string,"+0.7) node[anchor=south east] {$\\mathsf{received\\,\\,sequence:}$};");  
for i = 1:segments_amount
rec_string = num2str(received_sequence(i,1));
if received_amount > 1    
  for j=1:(received_amount-1)
    rec_string = strcat(rec_string,",",num2str(received_sequence(i,j+1)));
  end
end    
tikz_sequence_one_string = "\n\\draw (";
tikz_sequence_two_string = ") node[anchor=south] {$(";
tikz_sequence_three_string = ")$};  ";
sequence_string = strcat(sequence_string,tikz_sequence_one_string,"\\xscale*",num2str(i-1),"+\\xscale/2,\\yscale*",states_num_string,"+0.7",tikz_sequence_two_string,rec_string,tikz_sequence_three_string);
end
sequence_string = strcat(sequence_string,"\n\\fi ");

% codeword estimate
codeest_string = strcat("\n\n % codeword estimate\n\\if\\showdecoding0\n\\else \n\\draw[red] (",num2str(0),",\\yscale*",states_num_string,"+1.125) node[anchor=south east] {$\\mathsf{codeword\\,\\,estimate:}$};");
only_string_1 = "\n\\only<";
only_string_2 = "-";
only_string_3 = ">{";
only_end = "}";
last_step = time_instances;
for i = 1:segments_amount
segment_lastpath = 1;
alive_count = 0;
ce_string = " ";
for m = 1:states_amount
  for n =1:2
    if lifespan(m,n,i)< nonexistent &&  (lifespan(m,n,i)+1)> segment_lastpath
      segment_lastpath = lifespan(m,n,i)+1;
    end
    if lifespan(m,n,i) == stillalive
      alive_count = alive_count+1;
      ce_state_temp = m;
      transition_count = n;         
    end
  end
end
if alive_count == 1
  if ce_state_temp > (states_amount/2)
    transition_type = 2; % "one"-transition
  else
    transition_type = 1; % "zero"-transition
  end
  origin_state_ce = entrys(ce_state_temp,transition_count*2,i+1);
  ce_string = strcat(ce_string, num2str(codewortbit_edge_outputs(origin_state_ce,1,transition_type)));
  if received_amount > 1
    for k = 2:received_amount
      ce_string = strcat(ce_string,", ", num2str(codewortbit_edge_outputs(origin_state_ce,k,transition_type)));
    end  
  end       
  ce_one_string = strcat(only_string_1,num2str(segment_lastpath),only_string_2,num2str(last_step),only_string_3,"\n\\draw[red] (");
  ce_two_string = " node[anchor=south] {$(";
  ce_three_string = ")$};  ";
  codeest_string = strcat(codeest_string,ce_one_string,"\\xscale*",num2str(i-1),"+\\xscale/2",",\\yscale*",num2str(states_amount-1),"+1.125)",ce_two_string,ce_string,ce_three_string,only_end);
end
end
codeest_string = strcat(codeest_string,"\n\\fi ");

% path metric
weights_string = "\n\n% path metric\n\\if\\showdecoding0\n\\else \n\\if\\pathmetric0\n\\else ";
only_string_1 = "\n\\only<";
only_string_2 = "-";
only_string_3 = ">{";
only_end = "}";
for j=1:time_instances
weights_string=strcat(weights_string,only_string_1,num2str(j-1),only_string_2,num2str(time_instances),only_string_3);
for i=1:states_amount
  if path_metric_array(i,j) < 1000
    tikz_weights_one_string = "\n\\node[pathmetric] at (";
    tikz_weights_two_string = strcat("-\\pathmetricposition) {");
    weights_string = strcat(weights_string,tikz_weights_one_string,"\\xscale*",num2str(j-1),",\\yscale*",num2str(-i),"+\\yscale*",num2str(states_amount),tikz_weights_two_string,num2str(path_metric_array(i,j)),"};");
  end
end
weights_string = strcat(weights_string,only_end);
end
weights_string = strcat(weights_string,"\\fi\n\\fi ");
end

% combine all TikZ code parts
if seq == 0
tikz_code_convolution_trellis = strcat(tikz_begin,tikz_styles,states_string,arrows_string,codewordbits_string,steps_string,dots_string,tikz_end);
else
tikz_code_convolution_trellis = strcat(tikz_begin,tikz_styles,states_string,decoding_path_string,codeest_string,arrows_string,codewordbits_string,steps_string,sequence_string,dots_string,weights_string,tikz_end);
end
############################################################# TIKZ END ###################################################################


basename = strrep(filename, '.png', '');
tikz_file = fopen(sprintf('%s.tex', basename), 'w');
fwrite(tikz_file, tikz_code_convolution_trellis);
fclose(tikz_file)



%cmd = 'pdflatex -output-directory=./tmp %s.tex; pdf2ps %s.pdf %s.ps; ps2eps -q %s.ps; convert -density 200 -resize 640x480 %s.eps %s.tikz.png ';    

cmd = 'pdflatex -output-directory=./tmp %s.tex; convert -density 200 -resize 2500x900 %s.pdf %s.tikz.png ';
cmd = strrep(cmd, '%s', basename);
fprintf('about to execute the command\n%s', cmd);
[status, output] = system(cmd);


if seq == 0
  for p=0:inue_js_animationNumberOfFrames-1
    copyfile(sprintf('%s.tikz.png', basename), sprintf('%s.png_%d', basename, p));  
  endfor 
else
  for p=0:segments_amount
    copyfile(sprintf('%s.tikz-%d.png', basename, p), sprintf('%s.png_%d', basename, p));  
  endfor 
  for p=segments_amount+1:inue_js_animationNumberOfFrames-1
    copyfile(sprintf('%s.tikz-%d.png', basename, segments_amount), sprintf('%s.png_%d', basename, p));  
  endfor 
endif

tikz_link = ['<a href=./',sprintf('%s.tex', basename),'> TikZ code of the ',code_string,' trellis</a>'];

endfunction


% functions
% converts octal string into bit string
function bit_string = octstr2bitstr (octal_string)
  acc = 0;
  for i = 1:length(octal_string)
    acc = acc*8 + str2num(octal_string(i));
  end
  bit_string = dec2bin(acc);
endfunction

% returns bit strings of the same length
function string_cell_array = pad_leading_zeros (cell_array_diff_length)
  gp_amount = length(cell_array_diff_length);
  gp_length = 0;
  for i=1:gp_amount
    len = length(cell_array_diff_length{i,1});
    if len > gp_length
      gp_length = len;
    end
  end
  for i=1:gp_amount
    zerostr = "";
    len = length(cell_array_diff_length{i,1});
    if len < gp_length
      for j=1:(gp_length - len)
        zerostr = strcat(zerostr,"0");
      end
    end
    string_cell_array{i,1} = strcat(zerostr,cell_array_diff_length{i,1});
  end
endfunction

% returns cell array of possible states
function states = states_cell_array (states_amount)
  for i=1:states_amount
    states_diff_length{i,1} = dec2bin(i-1);
  end
  states = pad_leading_zeros(states_diff_length);
endfunction

% returns array with transition arrivals for each state
function state_transitions = state_transitions (states)
  for t = 1:2 % 1:"zero"-transition 2:"one"-transition
    transition_type = num2str(t-1); % "zero" or "one"
    for i=1:length(states)
      state = states{i,1};
      state_len = length(state);
      state_temp = "";
      for j = 1: (state_len-1)
        state_temp = strcat(state_temp,state(j));
      end
      state_transitions{i,t} = bin2dec(strcat(transition_type,state_temp));
    end
  end
endfunction

% returns edge outputs of transitions between states
function edge_outputs = edge_outputs_array(states,gp_bits)
  for t = 1:2 % 1:"zero"-transition 2:"one"-transition
    transition_type = num2str(t-1); % "zero" or "one"
    edge_outputs(length(states),length(gp_bits),t) = 0;
    for i = 1:length(states)
      shift_register_entry = fliplr(strcat(transition_type,states{i,1}));
      for j = 1:length(gp_bits)
        gp = gp_bits{j,1};
        for k = 1: length(gp)
          gp_position = str2num(gp(k));
          states_position = str2num(shift_register_entry(k));
          edge_outputs(i,j,t) = rem((edge_outputs(i,j,t) + gp_position*states_position),2);
        end
      end
    end
  end
endfunction