function[finalStream] = splitStreams(splitLength, StreamData, sampleDist)
%this FUNCTION will calculate the length of each stream and then split the
%stream into smaller segments to facilitate lidar processing.

% 8/4/2011: recently added a 5th column to the streams data that represents the width
%of the stream at that location


%{
%------------BEGIN for testing only *****************************
clear
clc
%streamFormat is now : StreamName VertexNum X Y (no additional data)
StreamData = dlmread('C:\1_Documents\1_Dissertation\1_Matlab_code\1_finalCode_SampleStreams\data\streamPoints_allClean4.csv',',',1,0);
% how long do i want each stream segment to be = splitLength below (in
% meters)
splitLength = 1000;
sampleDist=100;
%------------END for testing only *****************************
%}

%define variables
o=1;
streamNumber=0;
newStreamName=0;
%unique streams (original data)
totalStreams= length(find(unique(StreamData(:,1))));
streamSplitNum=0;
splitCoord=[];

% begin loop through each original stream segment, measure total length,
% split into segments

for Name = 1:totalStreams
%for Name = 1:15 %temporary for testing on one stream reach instead of the entire thing at once
    %keep track of how many streams have been run
  
    
   %% 
    %calculate the length of the entire segment & populate the cumulative
    %length for all vertices in the original stream 
    

    % find verticies for each stream segment within each stream    
    A = find(StreamData(:,1) == Name);

    % number of verticies in entire stream segment
    L = length(A);

    % Order of points (order located in column 2 of the stream data (vertexnum))
    Order = StreamData(A(1:end),2); %going to try to replace order with A throughout...
    
    Stream_coord=[];
    % Find stream vertex coordinates
    Stream_coord = (StreamData(A,3:5));

    % removed the sort command - not needed?
    %Stream_coord = Stream_temp(A,:);
    %Stream_coord = Stream_temp;
        
    % preallocate stream segment for L (total stream vertices) and x and Y)
    p1_stream = zeros((L-1),2);
    p2_stream = zeros((L-1),2);
    dist_ft = zeros((L-1),1);
    dist_sum = zeros(L,1);
  
    % Solve for the distance between stream verticies

    for j = 1:L-1
        p1_stream(j,:) = [Stream_coord(j,1) Stream_coord(j,2)]; %first stream vertext coordinate
        p2_stream(j,:) = [Stream_coord(j+1,1) Stream_coord(j+1,2)]; %second stream vertext coordinate

        % distance between 2 points
        dist_ft(j) = sqrt((p2_stream(j,1)-p1_stream(j,1))^2+(p2_stream(j,2)-p1_stream(j,2))^2);

        % convert length from ft to meters
        dist = 0.3048*dist_ft;
        
    end

    % Calculate cummulative stream length starting at first point given in file
    for k = 2:L-1
        dist_sum(1) = 0;
        dist_sum(2) = dist(1); % pull the distance between the vertices (dist matrix)
        dist_sum(k+1) = dist_sum(k)+dist(k);
    end

    
        
        
    % *********** END calculate stream vertices and sample pts along stream *****************   
%%
%check to see if the length of the segments is less than the sampling
%distance. if it is... move on to the next stream (discard the stream)

if (max(dist_sum)) < sampleDist
    % disp('stream is too short')
    %then move on to next stream 
else
   
% continue calculating stream split length
    
    % calculate number of split points / segments for the stream
    % extract / calculate vertex coordinate points bounding each stream segment

    %number of segments to split the stream into
    NumOfStreamSegs = floor(max(dist_sum/splitLength));

    %preallocate seg matrix (which holds the index location of each segment
    %split point within the stream 
     seg=zeros((NumOfStreamSegs),1); 

     %calculate split points (index values)
        for n = 1:NumOfStreamSegs;
        seg(n) = find(dist_sum < splitLength*n, 1, 'last' ); 
        end
    
    
    %Preallocate matrices to be used to hold vertex coordinate locations
    p1_seg=zeros((length(seg)),2); %preallocate for seg matrices
    p2_seg=zeros((length(seg)),2);
    seg_dist=zeros((length(seg)),1);
    alpha=zeros((length(seg)),1);
    m=zeros((length(seg)),1);   
    
    %if the stream is already short (can't be divided any further ie
    %segments = 0, then populate the matrix
    
    if NumOfStreamSegs < 1
        %clear out temp finalStream matrix
        finalStreamSeg=[]; 
        newStreamName=newStreamName+1;
          
          %loop through and assign the new stream name and vertex number
          %to each vertex in the stream segment
          for h=1:L 
            finalStreamSeg(h,:) = [Name newStreamName o Stream_coord(h,1:3)];
            o=o+1; 
          end
          
    else
        %begin looping through and splitting stream into segments
        streamSplitNum=streamSplitNum+1;
          
         splitCoord_temp=[];
        for i=1:NumOfStreamSegs

            %if we are on segment 2, then make sure to record the previous last
            %vertex (at the split point) to be used as the first coordinate of
            %the new stream segment
            if i > 1
            firstCoordNext=[px py];
            end

           % clear out temporary matrices (might be able to preallocate in the
           % future
            streamSeg_temp=[];


            %name for next stream segment
            newStreamName=newStreamName+1;

            %define coordinate locations for the vertices of the first segment
            p1_seg(i,:) = p1_stream(seg(i),:);
            p2_seg(i,:) = p2_stream(seg(i),:);


            % calculate the distance along the line between p1 and p2 that = splitLength
        seg_dist(i) = splitLength*i - dist_sum(seg(i));

        % calculate slope between p1 and p2 for seg(i)
        % if the line is vertical (the x values are the same) then the slope can't
        % be calculated
        if p2_seg(i,1) == p1_seg(i,1)
            m(i)=NaN;
        else
        m(i) = (p2_seg(i,2)-p1_seg(i,2))/(p2_seg(i,1)-p1_seg(i,1));
        end

        % convert slope to angle (radians)
        alpha(i) = atan(m(i));

        % find the split point coordinates along stream segment "seg_dist" from p1 (the starting
        % point)
        %this function accounts for slopes of 0 and NaN...
        [px py]=calculateNewXY(p1_seg(i,:), p2_seg(i,:), seg_dist(i), alpha(i));



        %define starting and ending coordinates for new segment (define where to break
        %the segments)
        if i == 1
            firstCoordIndex=1;
        else
            firstCoordIndex = (seg(i-1)+1);
        end
            lastCoordIndex= seg(i);

         %populate the vertex values for the new stream segment (up to the split - add the split coordinate in the next step)

        % if we are on segment 2 or more, then add the end of the last segment as the 
        % first coordinate for the next stream segment 
        if i > 1
           streamSeg_temp = [Name newStreamName o firstCoordNext(1,1:2) Stream_coord(u,3)];
           o=o+1; %vertex number
           z=2;
        else
           z=1;
        end

        %populate the rest of the vertices (or all of the vertices if we are on
        %the first segment
        for u=firstCoordIndex:lastCoordIndex  
            streamSeg_temp(z,:) = [Name newStreamName o Stream_coord(u,1:3)];
            z=z+1;
            o=o+1;
        end   

        %now add the  split coordinate location along the line (this will be the
        %LAST coordinate vertext of / added to the current stream) it will also 
        %be the FIRST coordinate vertex for the next segment - only do this if
        %i<num of segments (ie don't do it for the last segment
        if i <= NumOfStreamSegs
        streamSeg_temp(z,:) = [Name newStreamName o px py Stream_coord(u,3)];
        z=z+1;
        o=o+1;
        end

        % after running the last segment, append any additional vertices that are beyond the last x-meter
        % segment distance (the stream was split into x m segments but there may
        % be additional length beyond the last even split)
        
        % add something that determines whether 
        
      
        %need to calculate how long the last segment that is shorter than
        %the split)
        lastSeg = max(dist_sum)-(splitLength*NumOfStreamSegs);
        
           if (i==NumOfStreamSegs) && (lastCoordIndex < L)
               
              if lastSeg > (splitLength * .2)   
                %name for next stream segment
                newStreamName=newStreamName+1;
                
                %add the calculated coordinate (the last coordinate of the
                %previous segment to the first coordinate of the last seg
                streamSeg_temp(z,:) = [Name newStreamName o px py Stream_coord(u,3)];
                z=z+1;
                o=o+1;

                %also need to task on the last coordinat to the beginning
                %of the next segment
                
              else
              end
                  
            for v = (lastCoordIndex+1):L  
                streamSeg_temp(z,:) = [Name newStreamName o Stream_coord(v,1:3)];
                z=z+1;
                o=o+1;
            end 
             
           end

        %create a temporary matrix of split coordinates for plotting
        splitCoord_temp(i,:)=[Name newStreamName px py];


        %populate all vertex values into one matrix representing the entire
        %original stream split into segments
        if i == 1
        finalStreamSeg=(streamSeg_temp);
        else
        finalStreamSeg=[finalStreamSeg; streamSeg_temp]; 
        end

        % END looping through stream segments to be split out
        
        end   
        
        
    end   

   
    
    %be sure to clear out finalStreamSeg before each segment loop
    %populate final stream matrix
    if newStreamName == 1 
        finalStream=(finalStreamSeg);
    else
        finalStream=[finalStream;finalStreamSeg];
    end
    
    %populate split coordinate matrix
    if NumOfStreamSegs > 0  
        if streamSplitNum == 1  %need a counter that only counts how many streams have been split
            splitCoord=(splitCoord_temp);
        else 
            splitCoord=[splitCoord;splitCoord_temp];
        end
    end
  
end
end

%calculate out length of streams
%then go through and remove stream segments that are shorter than the
%sample distance...

%then output final streams

disp('Finished Processing & Splitting All Streams... time to calculate transects')

%{
%************************** BEGIN Turn off Plot *************************
%plot everything out

figure(2)
 plot(p1_seg(:,1),p1_seg(:,2),'rs','LineWidth',1.25,'MarkerSize',10), hold on
 
 if isempty(splitCoord)
 else
 plot(splitCoord(:,3),splitCoord(:,4),'g*','LineWidth',1.25,'MarkerSize',20), hold on
 end
 %create a random colormap
 
%cmap = hsv(6);  %# Creates a 6-by-3 set of colors from the HSV colormap  
%calculate number of new unique streams (after split)
allStreamsLen = length(find(unique(finalStream(:,2))));
cmap = hsv(allStreamsLen);  %# Creates a n-by-3 set of colors from the HSV colormap 
for f=1:allStreamsLen
%for f=50:74 
%vertices=AllStreamLength(f,3);
    A2=zeros(1000);
    A2 = find(finalStream(:,2) == f); 
    % number of verticies in stream segment
    %L2 = length(A2);
    plot(finalStream((A2(:)),4),finalStream((A2(:)),5),'--o','LineWidth',3.25,'MarkerSize',2,'Color',cmap(f,:)), hold on
end
 
 

 %plot(StreamData(:,3),StreamData(:,4),'--bo','LineWidth',1.25,'MarkerSize',5), hold on 
 %plot all streams

%%
%
%plot streams data or one particular stream
%}
%{
for f=121:121
    %vertices=AllStreamLength(f,3);
   % A2=zeros(vertices);
    A2 = (find(StreamData(:,1) == f)); 
    % number of verticies in stream segment
    L2 = length(A2);
    plot(StreamData((A2(:,1)),3),StreamData((A2(:,1)),4),'--go','LineWidth',1.25,'MarkerSize',2), hold on
end
 
%} 

%************************** END Turn off Plot *************************
%}
