function photoCollection() {
	// ------- kolekce fotek ---------
	this.baseContainer = null;

	this.collection = new Array();
	this.indexes = new Array();

	this.handleVisiblity = false;
	this.tagParsing = true;
	this.printSelect = null;
	this.printCountChange = null;
	
	this.big_prev = "_B";
	this.small_prev = "_B";

	this.vis_collection = new Array();
	this.vis_indexes = new Array();

	this.exist = function(photoID) {
		return (this.indexes[photoID] != null);
	}

	this.index = function(photoObj) {
		this.indexes[photoObj.photo_ID] = photoObj;
	}

	this.swap = function(photoObjA, photoObjB) {
		swapNodes(this.baseContainer, photoObjA.container, photoObjB.container);

		// swap pozic
		var befPosition = photoObjA.position;
		var befAlbum_ID = photoObjA.album_ID;

		photoObjA.position = photoObjB.position;
		photoObjA.album_ID = photoObjB.album_ID;
		photoObjB.position = befPosition;
		photoObjB.album_ID = befAlbum_ID;

		// swap mapovani
		this.mapSwap(photoObjA.map_xIndex, photoObjA.map_yIndex, photoObjB.map_xIndex, photoObjB.map_yIndex);
	}

	this.addVisible = function(photoObj) {
        if (this.vis_indexes[ photoObj.photo_ID ] == null) {
            this.vis_collection[this.vis_collection.length] = photoObj;
            this.vis_indexes[ photoObj.photo_ID ] = photoObj;
        }
    }
    
    this.remVisible = function(photoObj) {
        if (this.vis_indexes[ photoObj.photo_ID ] != null) {
            var pos = 0;
            while (this.vis_collection[pos] != photoObj) pos++;
            
            for (var f = pos; f < this.vis_collection.length - 1; f++)
                this.vis_collection[f] = this.vis_collection[f + 1];

            this.vis_collection.pop();

            this.vis_indexes[ photoObj.photo_ID ] = null;
        }
    }

	this.add = function(photoObj) {
		this.collection[this.collection.length] = photoObj;
		this.index(photoObj);
		if (this.handleVisiblity)
		    this.addVisible(photoObj);

		return photoObj;
	}

	this.find = function(photoObj) {
        var founded = false;
        var pos = 0;

        while (pos < this.collection.length && !founded)
            if (this.collection[pos] == photoObj) founded = true;
            else pos++;

        return founded ? pos : -1;
    }

	this.addParamsSpec = function(iContainerObj, iPhotoID, iTitle, iComment, iTags, iAlbumNum, setTo, simpleFlag, loadPath) {
        var ref = null;
		if ( !this.exist(iPhotoID) ) {
            ref = new photo(iContainerObj, iPhotoID, iTitle, iComment, iTags, iAlbumNum, this, simpleFlag, loadPath);
			this.add( ref );
		} else {
			ref = this.indexes[iPhotoID];
    		ref.updateContainer(iContainerObj);
    		ref.updateImage();
		}

		switch (setTo) {
			case 0 : ref.uncheck(); break;
			case 1 : ref.check(); break;
			case 2 : ref.call(); break;
		}
		return ref;
	}

	this.addParams = function(iContainerObj, iPhotoID, iTitle, iComment, iTags, iAlbumNum, simpleFlag, loadPath) {
		return this.addParamsSpec(iContainerObj, iPhotoID, iTitle, iComment, iTags, iAlbumNum, 1, simpleFlag, loadPath);
	}

	this.addBatch = function(baseContainer, photoData) {
		var photoRef = null;
		this.baseContainer = baseContainer;

		for (var f = 0; f < baseContainer.childNodes.length && f < photoData.length; f++) {
			if ( !this.exist(photoData[f][0]) ) {
                photoRef = this.addParamsSpec(baseContainer.childNodes[f], photoData[f][0], photoData[f][1], photoData[f][2], photoData[f][3], photoData[f][4], photoData[f].length == 5 ? null : photoData[f][5], photoData[f].length == 7 ? 1 : null);
			} else photoRef = this.indexes[photoData[f][0]].call();

			if (photoData[f].length == 7) { // nastaveni pozice
				photoRef.assignPhoto(photoData[f][5], photoData[f][6]);
			}
		} // for
	}

    this.addBatchBuild = function(baseContainer, photoData, visiblePhotos, checkPhotos) {
        var photoRef = null;

        var baseEl = null;
        var topEl = null;
        var bottomEl = null;
        var subEl = null;

        this.baseContainer = baseContainer;

        for (var f = 0; f < photoData.length; f++) {
            if ( !this.exist(photoData[f][0]) ) {
                baseEl   = document.createElement("DIV");
                topEl    = document.createElement("IMG");
                bottomEl = document.createElement("DIV");

                baseEl.style.width = "110px";
                baseEl.style.height = "130px";
                baseEl.style.cssFloat = "left";
                baseEl.style.styleFloat = "left";
                baseEl.style.textAlign = "center";
                baseEl.style.marginRight = "5px";
                baseEl.style.marginBottom = "5px";

                topEl.src = "";

                baseEl.appendChild( topEl );
                baseEl.appendChild( bottomEl );

                this.baseContainer.appendChild( baseEl );
                photoRef = this.addParamsSpec(baseEl, photoData[f][0], photoData[f][1], photoData[f][2], photoData[f][3], photoData[f][4], photoData[f].length == 5 ? 1 : photoData[f][5]);

                if (photoData[f].length == 8) {
                    // update obrazku
                    photoRef.updateSourceForce( photoData[f][7][0], photoData[f][7][1], photoData[f][7][2] );
                    // update rozliseni
                    photoRef.flag_resX = photoData[f][7][3];
                    photoRef.flag_resY = photoData[f][7][4];
                    // update alba
                    if (photoData[f][7].length >= 6) photoRef.album_ID = photoData[f][7][5];
                    // update poctu
                    if (photoData[f][7].length >= 7) photoRef.count = photoData[f][7][6];
                }

                baseEl   = null;
                topEl    = null;
                bottomEl = null;

                if (!visiblePhotos) photoRef.hideForce();
                if (checkPhotos) photoRef.check();
            } else {
                if (visiblePhotos) this.indexes[ photoData[f][0] ].visible();
                else this.indexes[ photoData[f][0] ].hideForce();
                if (checkPhotos) photoRef.check();
            }
        } // for
        
        return true;
    }

	this.uncheck = function() {
		for (var f = 0; f < this.collection.length; f++)
			this.collection[f].uncheck();
	}

	this.check = function() {
		for (var f = 0; f < this.collection.length; f++)
			this.collection[f].check();
	}
	
	this.checkString = function() {
        var started = true;
        var output  = "";

        for (var f = 0; f < this.collection.length; f++) {
            if (this.collection[f].selected) {
                if (started) started = false;
                else output += "|";
                output += this.collection[f].photo_ID;
            }
        }
        
        return output;
    }
	
	this.firstChecked = function() {
        var pos = 0;
        var brk = false;

        while (pos < this.collection.length && !brk)
            if (this.collection[pos].selected) brk = true;
            else pos++;

        return brk ? this.collection[pos] : null;
    }

	// mapovani pozic
	this.posMap = new Array(); // asociativni pole
	this.map_defWidth  = 0;
	this.map_defHeight = 0;
	this.map_startX	   = 0;
	this.map_startY	   = 0;
	
	this.mapPositions = function() {
		var ref = null;
		var pos;
		
		var xIndex = 0;
		var yIndex = 0;
		
		var f = 0;
		
		this.map_startX = elementPositionX(this.baseContainer);
		this.map_startY = elementPositionY(this.baseContainer);
		
		if (this.collection.length > 0) {
			this.map_defWidth  = parseInt(this.collection[0].container.style.width);
			this.map_defHeight = parseInt(this.collection[0].container.style.height) + 5;

			for (f = 0; f < this.collection.length; f++) {
				var pos = elementPosition(this.collection[f].container);

				var xIndex = Math.floor((pos[0] - this.map_startX) / this.map_defWidth);
				var yIndex = Math.floor((pos[1] - this.map_startY) / this.map_defHeight);

				this.mapSpec(this.collection[f], xIndex, yIndex);
			}
		} // if
	}

	this.mapSpec = function(photoObj, xIndex, yIndex) {
		if (this.posMap[yIndex] == null) {
			this.posMap[yIndex] = new Array();
			this.posMap[yIndex][xIndex] = photoObj;
		} else this.posMap[yIndex][xIndex] = photoObj;

		this.posMap[yIndex][xIndex] = photoObj;
		
		photoObj.map_xIndex = xIndex;
		photoObj.map_yIndex = yIndex;
	}
	
	this.mapSwap = function(xIndexA, yIndexA, xIndexB, yIndexB) {
		var refA = this.posMap[yIndexA][xIndexA];
		var refB = this.posMap[yIndexB][xIndexB];

		this.mapSpec(refA, xIndexB, yIndexB);
		this.mapSpec(refB, xIndexA, yIndexA);
	}
	
	this.getMapped = function(iX, iY) {
		var xIndex = Math.floor((iX - this.map_startX) / this.map_defWidth);
		var yIndex = Math.floor((iY - this.map_startY) / this.map_defHeight);
		
		//alert(xIndex + " | " + yIndex);
		
		if (xIndex >= 0 && yIndex >= 0)
			if (this.posMap[yIndex] != null) return this.posMap[yIndex][xIndex];
		
		return null;
	}
	
	// drag & drop
	this.drag_selfRef   = null;
	this.drag_targetRef = null;
	this.drag_img		= null;
	this.drag_diffX     = 0;
	this.drag_diffY		= 0;

	this.dragStart = function(photoRef, iX, iY) {
		this.drag_selfRef = photoRef;
		this.drag_selfRef.fade();

        // prenaseny obrazek
		this.drag_img = document.getElementById("drag_img");

		this.drag_img.src 	 = this.drag_selfRef.image.src;
		this.drag_img.width  = this.drag_selfRef.image.width;
		this.drag_img.height = this.drag_selfRef.image.height;

		var imgPosX = elementPositionX(this.drag_selfRef.image);
		var imgPosY = elementPositionY(this.drag_selfRef.image);

		this.drag_diffX	= iX - imgPosX;
		this.drag_diffY = iY - imgPosY;

		this.drag_img.style.position = "absolute";
		this.drag_img.style.left = (iX - this.drag_diffX) + "px";
		this.drag_img.style.top  = (iY - this.drag_diffY) + "px";
		this.drag_img.style.display = "block";
	}
	
	this.dragOver = function(iX, iY) {
		if (this.drag_img != null) {
			var newRef = this.getMapped(iX, iY);
			if (newRef != null && newRef != this.drag_targetRef) {
				//this.drag_targetRef = newRef;
				//this.swap(this.drag_selfRef, this.drag_targetRef);
				//this.baseContainer.insertBefore(this.drag_selfRef.container, newRef.container);
			}

			this.drag_img.style.left = (iX - this.drag_diffX) + "px";
			this.drag_img.style.top  = (iY - this.drag_diffY) + "px";
		}
	}

	this.dragEnd = function(iX, iY) {
		var newRef = this.getMapped(iX, iY);
		if (newRef != null && newRef != this.drag_targetRef) {
			this.drag_targetRef = newRef;

			//this.swap(this.drag_selfRef, this.drag_targetRef);
			this.drag_selfRef.visible();

            var thisIndex = this.find(this.drag_selfRef);
            var refIndex = this.find(this.drag_targetRef);

            if (thisIndex != -1 && refIndex != -1) {
                var f;

                var befX = new Array();
                var befY = new Array();

                if (refIndex < thisIndex) {
                    for (f = refIndex; f <= thisIndex; f++) {
                        befX[befX.length] = this.collection[f].map_xIndex;
                        befY[befY.length] = this.collection[f].map_yIndex;
                    }

                    var newPos = this.collection[refIndex].position;

                    for (f = thisIndex; f > refIndex; f += -1) {
                        this.collection[f] = this.collection[f - 1];
                        this.collection[f].position++;
                        this.mapSpec(this.collection[f], befX[f - refIndex], befY[f - refIndex]);
                    }

                    this.collection[refIndex] = this.drag_selfRef;
                    this.collection[refIndex].position = newPos;
                    this.mapSpec(this.collection[refIndex], befX[0], befY[0]);

                    this.baseContainer.removeChild(this.drag_selfRef.container);
        			this.baseContainer.insertBefore(this.drag_selfRef.container, this.drag_targetRef.container);
                } else {
                    for (f = thisIndex; f <= refIndex; f++) {
                        befX[befX.length] = this.collection[f].map_xIndex;
                        befY[befY.length] = this.collection[f].map_yIndex;
                    }

                    var newPos = this.collection[refIndex].position;

                    for (f = thisIndex; f < refIndex; f++) {
                        this.collection[f] = this.collection[f + 1];
                        this.collection[f].position += -1;
                        this.mapSpec(this.collection[f], befX[f - thisIndex], befY[f - thisIndex]);
                    }

                    this.collection[refIndex] = this.drag_selfRef;
                    this.collection[refIndex].position = newPos;
                    this.mapSpec(this.collection[refIndex], befX[befX.length - 1], befY[befY.length - 1]);

                    this.baseContainer.removeChild(this.drag_selfRef.container);
                    if (refIndex + 1 < this.collection.length) {
                        this.drag_targetRef = this.collection[refIndex + 1];
            			this.baseContainer.insertBefore(this.drag_selfRef.container, this.drag_targetRef.container);
        			} else {
                        this.baseContainer.appendChild(this.drag_selfRef.container);
                    }
                }

                /*
                for (f = 0; f < this.collection.length; f++) {
                    if (this.collection[f].container.childNodes.length == 1) {
                        var tmp = document.createElement("DIV");
                        tmp.innerHTML = this.collection[f].position + " (" + this.collection[f].map_xIndex + ", " + this.collection[f].map_yIndex + ")";

                        this.collection[f].container.appendChild(tmp);
                    } else {
                        this.collection[f].container.childNodes[1].innerHTML = this.collection[f].position + " (" + this.collection[f].map_xIndex + ", " + this.collection[f].map_yIndex + ")";
                    }
                } */

            } else alert("nastala chyba");
		}

		this.drag_img.style.display = "none";
		this.drag_img = null;

		this.drag_selfRef   = null;
		this.drag_targetRef = null;
	}
}

