/* Copyright 2008 we-lab-doc! (http://www.we-lab-doc.com/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.we_lab_doc.spacecard.model

import org.codehaus.groovy.grails.commons.GrailsClassUtils
import com.we_lab_doc.spacecard.utils.StringUtils as SU

/**
 * @author Shigeru GOUGI
 * @since 0.1
 *        <p/>
 *        Created: February 20, 2008
 */
class CollectionBugEvasion {
	
	static def addToForBidirectionalManyToOne (owner, Class ownerType, otherSide, Class otherSideType, propName, otherSideName) {
		return addToForBidirectional(false, owner, ownerType, otherSide, otherSideType, propName, otherSideName)
	}
	
	static def addToForBidirectionalManyToMany (owner, Class ownerType, otherSide, otherSideType, propName, otherSideName) {
		return addToForBidirectional(true, owner, ownerType, otherSide, otherSideType, propName, otherSideName)
	}
	
	static private def addToForBidirectional(boolean isManyToMany, owner, Class ownerType, otherSide, Class otherSideType, propName, otherSideName) {
        Object obj
        if (owner[propName] == null) {
            owner[propName] = GrailsClassUtils.createConcreteCollection(ownerType)
        }
        if (otherSide instanceof Map) {
        	throw new IllegalStateException("not supported")
        } else if (otherSide != null) {
            obj = otherSide
            owner[propName].add(obj)
        } else {
            throw new IllegalStateException("addTo${SU.toFirstLetterUpperCase(propName)} : $owner")
        }
       	if(isManyToMany){
       		if (!obj[otherSideName]) {
       			obj[otherSideName] = GrailsClassUtils.createConcreteCollection(otherSideType)
       		}
       		obj[otherSideName].add(owner)       	
       	} else {
       		obj[otherSideName] = owner
       	}
        owner
	}	
	
	static def removeFromForBidirectionalManyToOne(owner, otherSide, propName, otherSideName) {
		return removeFromForBidirectional(false, owner, otherSide, propName, otherSideName)
	}
	
	static def removeFromForBidirectionalManyToMany(owner, otherSide, propName, otherSideName) {
		return removeFromForBidirectional(true, owner, otherSide, propName, otherSideName)
	}
	
	static private def removeFromForBidirectional(boolean isManyToMany, owner, otherSide, propName, otherSideName) {
        if (otherSide != null) {
            owner[propName]?.remove(otherSide)
            if (isManyToMany) {
            	otherSide[otherSideName]?.remove(owner)
          	} else {
          		otherSide[otherSideName] = null
            }
        }
        else {
            throw new IllegalStateException("removeFrom${SU.toFirstLetterUpperCase(propName)} : $owner ")
        }     
        owner
	}	
	
}