function [trainindex,validindex,testindex,numTrain] = SampleSelect(Groundtruth,trainnumber)
%[trainindex,validindex,testindex]=SampleSelect(Groundtruthmap,trainnumber)
%
%select training, valid and testing samples
%Input:
%   Groundtruthmap:	the given training map
%   trainnumber:    number of training samples,if trainnumber<1,select the corresponding percent of each class
%           0<trainnumber<0.5:  (trainnumber * nPixel(iClass)) of samples per class are used for
%                   training, the same number used for validation, others for testing;
%           0.5<=trainnumber<1  (trainnumber * nPixel(iClass)) of samples per class are used for
%                   training, others for validation
%           trainumber == 1:    all the samples are used for testing
%           trainnumber>1:      (trainnumber) of samples per class are used for training, the same 
%                   number used for validation, others for testing
%return:
%   trainindex:     indices of training samples;
%   validindex:     indices of valid samples;
%   testindex:      indices of testing samples;
Groundtruth = Groundtruth(:);

labelindx = unique(Groundtruth(:));
labelindx = setdiff(labelindx,0);
nclass = length(labelindx);
nPixel = zeros(1,nclass);%sample quantity of each class
trainindex = [];
validindex = [];
testindex = [];
%---find all the given samples in the ground truth map---%
if trainnumber == 1
    %  trainumber == 1 indicates all the samples are used for testing
    testindex = find(Groundtruth~=0);
else
    for nnClass=1:nclass
        iClass = labelindx(nnClass);
        sampclass = find(Groundtruth == iClass);
        nPixel(iClass) = length(sampclass);
        nSampleDistance = randperm(nPixel(iClass));
        if 0<trainnumber && trainnumber<0.5
            % 0<trainnumber<0.5 indicates (trainnumber * nPixel(iClass)) of samples are used for
            % trainging, the same number used for validation, others for testing
            numTrain = floor(trainnumber * nPixel(iClass));
            trainindex = [trainindex;sampclass(nSampleDistance(1 : numTrain))];
            validindex = [validindex;sampclass(nSampleDistance(numTrain+1 : 2*numTrain))];
            testindex = [testindex;sampclass(nSampleDistance(2*numTrain+1 : nPixel(iClass)))];
        elseif 0.5<=trainnumber && trainnumber<1
            % 0.5<=trainnumber<1 indicates (trainnumber * nPixel(iClass)) of samples are used for
            % trainging, others for validation
            numTrain = floor(trainnumber * nPixel(iClass));
            trainindex = [trainindex;sampclass(nSampleDistance(1 : numTrain))];
            validindex = [validindex;sampclass(nSampleDistance(numTrain+1 : nPixel(iClass)))];
        else
            % trainnumber>1 indicates (trainnumber) of samples are used for training, the same 
            % number used for validation, others for testing
            numTrain = trainnumber;
            trainindex = [trainindex;sampclass(nSampleDistance(1 : numTrain))];
            if 2*numTrain<=nPixel(iClass)
                validindex = [validindex;sampclass(nSampleDistance(numTrain+1 : 2*numTrain))];
                testindex = [testindex;sampclass(nSampleDistance(2*numTrain+1 : nPixel(iClass)))];
            else
                validindex = [validindex;sampclass(nSampleDistance(numTrain+1 : nPixel(iClass)))];
                testindex = [testindex;sampclass(nSampleDistance(numTrain+1 : nPixel(iClass)))];
            end
        end
    end
end
if trainnumber>1
    numTrain = trainnumber;
else
    numTrain = floor(trainnumber * nPixel);
end