/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.
*/

use arch;
use xxx::big;
use xxx::big::BIG;
use arch::Chunk;

//#[derive(Copy, Clone)]
pub struct DBIG {
 	pub w: [Chunk; big::DNLEN]
}

impl DBIG {
   pub fn new() -> DBIG {
        DBIG {
        	w: [0; big::DNLEN as usize]
         }
    }	

    pub fn new_copy(y:&DBIG) -> DBIG {
    	let mut s= DBIG::new();   
    	for i in 0..big::DNLEN {s.w[i]=y.w[i]}
    	return s;	
    }

    pub fn new_scopy(x:&BIG) -> DBIG {
    	let mut b= DBIG::new();   
		for i in 0 ..big::NLEN {
			b.w[i]=x.w[i];
		}
		b.w[big::NLEN-1]=x.get(big::NLEN-1)&big::BMASK; /* top word normalized */
		b.w[big::NLEN]=x.get(big::NLEN-1)>>big::BASEBITS;

		for i in big::NLEN+1 ..big::DNLEN {b.w[i]=0}
    	return b; 	
    }

/* split DBIG at position n, return higher half, keep lower half */
    pub fn split(&mut self,n: usize) -> BIG
    {
        let mut t=BIG::new();
        let m=n%big::BASEBITS;
        let mut carry=self.w[big::DNLEN-1]<<(big::BASEBITS-m);
    
        for i in (big::NLEN-1..big::DNLEN-1).rev() {
            let nw=(self.w[i]>>m)|carry;
            carry= (self.w[i]<<(big::BASEBITS-m))&big::BMASK;
            t.set(i+1-big::NLEN,nw);
        }
        self.w[big::NLEN-1]&=((1 as Chunk)<<m)-1;
        return t;
    }

/* general shift left */
    pub fn shl(&mut self,k: usize)
    {
        let n=k%big::BASEBITS; 
        let m=k/big::BASEBITS; 
        self.w[big::DNLEN-1]=((self.w[big::DNLEN-1-m]<<n))|(self.w[big::DNLEN-m-2]>>(big::BASEBITS-n));
        for i in (m+1..big::DNLEN-1).rev() {
            self.w[i]=((self.w[i-m]<<n)&big::BMASK)|(self.w[i-m-1]>>(big::BASEBITS-n));
        }
  
        self.w[m]=(self.w[0]<<n)&big::BMASK;
        for i in 0 ..m {self.w[i]=0}
    }

/* general shift right */
    pub fn shr(&mut self,k: usize) {
		let n=k%big::BASEBITS;
		let m=k/big::BASEBITS;
        for i in 0 ..big::DNLEN-m-1 {
            self.w[i]=(self.w[m+i]>>n)|((self.w[m+i+1]<<(big::BASEBITS-n))&big::BMASK);
        }
        self.w[big::DNLEN-m-1]=self.w[big::DNLEN-1]>>n;
        for i in big::DNLEN - m ..big::DNLEN {self.w[i]=0}
    }

/* Copy from another DBIG */
	pub fn copy(&mut self,x: &DBIG) {
		for i in 0 ..big::DNLEN {
			self.w[i]=x.w[i];
		}
	}

    pub fn ucopy(&mut self,x: &BIG) {
        for i in 0 ..big::NLEN {
            self.w[i]=0;
        }
        for i in big::NLEN ..big::DNLEN {
            self.w[i]=x.w[i-big::NLEN];
        }        
    }    

	pub fn cmove(&mut self,g:&DBIG,d: isize) {
		let b=-d as Chunk;
		for i in 0 ..big::DNLEN {
			self.w[i]^=(self.w[i]^g.w[i])&b;
		}
	}

/* self+=x */
    pub fn add(&mut self,x:&DBIG) {
        for i in 0 ..big::DNLEN {
            self.w[i]+=x.w[i]; 
        }
    } 

/* self-=x */
	pub fn sub(&mut self,x:&DBIG) {
		for i in 0 ..big::DNLEN {
			self.w[i]-=x.w[i]; 
		}
	} 

/* self=x-self */
    pub fn rsub(&mut self,x:&DBIG) {
        for i in 0 ..big::DNLEN {
            self.w[i]=x.w[i]-self.w[i]; 
        }
    } 


/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
    pub fn comp(a: &DBIG,b: &DBIG) -> isize {
        for i in (0 ..big::DNLEN).rev() {
            if a.w[i]==b.w[i] {continue}
            if a.w[i]>b.w[i] {return 1}
            else  {return -1}
        }
        return 0;
    }

/* normalise BIG - force all digits < 2^big::BASEBITS */
    pub fn norm(&mut self) {
        let mut carry=0 as Chunk;
        for i in 0 ..big::DNLEN-1 {
            let d=self.w[i]+carry;
            self.w[i]=d&big::BMASK;
            carry=d>>big::BASEBITS;
        }
        self.w[big::DNLEN-1]+=carry
    }

/* reduces self DBIG mod a BIG, and returns the BIG */
    pub fn dmod(&mut self,c: &BIG) -> BIG {
        let mut k=0;
        self.norm();
        let mut m=DBIG::new_scopy(c);
        let mut dr=DBIG::new();
    
        if DBIG::comp(self,&m)<0 {
        	let r=BIG::new_dcopy(self);
        	return r;
        }
    
        loop {
            m.shl(1);
            k += 1;
            if DBIG::comp(self,&m)<0 {break;}
        }
    
        while k>0 {
            m.shr(1);

		dr.copy(self);
		dr.sub(&m);
		dr.norm();
		self.cmove(&dr,(1-((dr.w[big::DNLEN-1]>>(arch::CHUNK-1))&1)) as isize);
/*
            if DBIG::comp(self,&m)>=0 {
				self.sub(&m);
				self.norm();
            } */
            k -= 1;
        }
        let r=BIG::new_dcopy(self);
        return r;
    }

/* return this/c */
    pub fn div(&mut self,c: &BIG) -> BIG {
        let mut k=0;
        let mut m=DBIG::new_scopy(c);
        let mut a=BIG::new();
        let mut e=BIG::new_int(1);
	let mut dr=DBIG::new();
	let mut r=BIG::new();
        self.norm();

        while DBIG::comp(self,&m)>=0 {
            e.fshl(1);
            m.shl(1);
            k+=1;
        }

        while k>0 {
            m.shr(1);
            e.shr(1);

		dr.copy(self);
		dr.sub(&m);
		dr.norm();
		let d=(1-((dr.w[big::DNLEN-1]>>(arch::CHUNK-1))&1)) as isize;
		self.cmove(&dr,d);
		r.copy(&a);
		r.add(&e);
		r.norm();
		a.cmove(&r,d);
/*
            if DBIG::comp(self,&m)>0 {
                a.add(&e);
                a.norm();
                self.sub(&m);
                self.norm();
            } */
            k-=1;
        }
        return a;
    }

/* return number of bits */
	pub fn nbits(&mut self) -> usize {
		let mut k=big::DNLEN-1;
		let mut s=DBIG::new_copy(&self);        
		s.norm();
		while (k as isize)>=0 && s.w[k]==0 {k=k.wrapping_sub(1)}
		if (k as isize) <0 {return 0}
		let mut bts=(big::BASEBITS as usize)*k;
		let mut c=s.w[k];
		while c!=0 {c/=2; bts+=1;}
		return bts;
	}

/* Convert to Hex String */
	pub fn to_string(&mut self) -> String {
		let mut s = String::new();
		let mut len=self.nbits();

		if len%4==0 {
			len/=4;
		} else {
			len/=4;
			len+=1;
		}

		for i in (0 ..len).rev() {
			let mut b=DBIG::new_copy(&self);
			b.shr(i*4);
			s=s + &format!("{:X}", b.w[0]&15);
		}
		return s;
	}	

}
